GZIP Output Compression in Compojure
29 Jan 2010
Compression can be handled by the server, jetty or apache but I prefer my applications handling most of their operations, so I settled on using a middleware function to add compression to parts of my application. Compojure uses middleware to selectively add functionality to handlers such as sessions. middleware functions takes handlers, after your handler completes processing the request, middleware gets a chance to transform the response, giving you a tool for abstracting common functionality.
(defn with-gzip [handler]
(fn [request]
(let [response (handler request)
out (java.io.ByteArrayOutputStream.)
accept-encoding (.get (:headers request) "accept-encoding")]
(if (and (not (nil? accept-encoding))
(re-find #"gzip" accept-encoding))
(do
(doto (java.io.BufferedOutputStream.
(java.util.zip.GZIPOutputStream. out))
(.write (.getBytes (:body response)))
(.close))
{:status (:status response)
:headers (assoc (:headers response)
"Content-Type" "text/html"
"Content-Encoding" "gzip")
:body (java.io.ByteArrayInputStream. (.toByteArray out))})
response))))
with-gzip handler first checks the client request, if the client supports gzip compression, it uses GZIPOutputStream to compress the response, add the header telling the client that it contains compressed content. If client doesn't support gzip encoding response is not compressed.
(defn hello-world [request]
{:status 200
:headers {}
:body "Hello, World!!"})
(decorate hello-world
(with-gzip))
decorate macro takes care of applying middleware to handler.
Lindenmayer System in Clojure
26 Jan 2010
An L-system or Lindenmayer system is a language, which means a set of strings that is made by the application using certain rules. L-systems can be used to generate fractals such as iterated function systems.
- variables : F
- constants : + -
- start : F
- rules : (F -> F+F-F-F+F)
Above grammar represents the Koch curve, where F means "draw forward", + means "turn left 90",and - means "turn right 90". Following is a simple implementation in Clojure to build sentences using grammars defined like this.
(defn variable? [grammer symbol]
(contains? (:variables grammer) symbol))
(defn apply-rules [grammer sentence]
(flatten
(map #(if (variable? grammer %) ((:rules grammer) %) %) sentence)))
(defn l-system [grammer n]
(loop[acc n sentence (:start grammer)]
(if (= 0 acc)
sentence (recur (dec acc) (apply-rules grammer sentence)))))
We take the axiom (start) and apply the rules n times, with each iteration we replace the variables with their corresponding rules, so the grammar above will grow such as,
- n=0: F
- n=1: F+F-F-F+F
- n=2: F+F-F-F+F+F+F-F-F+F-F+F-F-F+F-F+F-F-F+F+F+F-F-F+F
Grammar for the Koch curve in Clojure is represented like so,
(def koch-curve
{:variables #{:F}
:constants #{:+ :-}
:start [:F]
:rules {:F [:F :+ :F :- :F :- :F :+ :F]}
:actions {:F forward :+ left :- right}
:angle 90
:step 10})
There are some additions to the grammar, such as what actions will be mapped to the variables while drawing, angles for the turns and a step value to determine how much to move forward or backward.
(defn draw-system [turtle grammer sentence]
(doseq [letter sentence]
(let [action (letter (:actions grammer))]
(cond
(or (= action forward) (= action back))
(action turtle (:step grammer))
(or (= action left) (= action right))
(action turtle (:angle grammer))))))
After creating a sentence for the fractal all we need to do is, iterate over the letters and command turtle to do the action that is mapped to the letter.
(def dragon-curve
{:variables #{:X :Y}
:constants #{:F :+ :-}
:start [:F :X]
:rules {:X [:X :+ :Y :F]
:Y [:F :X :- :Y]}
:actions {:F forward :+ left :- right}
:angle 90
:step 10})

(def pentigree
{:variables #{:F}
:constants #{:+ :-}
:start [:F :- :F :- :F :- :F :- :F]
:rules {:F [:F :- :F :+ :+ :F :+ :F :- :F :- :F]}
:actions {:F forward :+ left :- right}
:angle 72
:step 10})

(def sierpinski-triangle
{:variables #{:A :B}
:constants #{:+ :-}
:start [:A]
:rules {:A [:B :- :A :- :B]
:B [:A :+ :B :+ :A]}
:actions {:A forward :B forward :+ left :- right}
:angle 60
:step 10})

Unit Testing Compojure Routes
22 Jan 2010
I was digging through the compojure sources to figure out a way to test the routes defined, assuming you have the following routes,
(defroutes web-app
(GET "/" (or (str "Hello, World!") :next))
(GET "/name" (or (str "Hello, " (params :name)) :next))
(ANY "*" [404 (content-type "text/html") (str "404")]))
You can test them using,
(defn request [resource web-app & params]
(web-app {:request-method :get :uri resource :params (first params)}))
(deftest test-routes
(is (= 200 (:status (request "/" web-app))))
(is (= "Hello, World!"
(:body (request "/" web-app))))
(is (= 200 (:status (request "/name" web-app {:name "Ali"}))))
(is (= "Hello, Ali"
(:body (request "/name" web-app {:name "Ali"})))))
Clojure OpenCV Detecting Movement
19 Jan 2010
I have been experimenting with OpenCV to use webcam as a control device. I've put together a sample application which uses difference between frames to detect movement and perform collision detection with objects on the screen.
(defn create-circle []
(let [x (rand-int (- width circle-radius))
y (rand-int (- height circle-radius))]
{:x x :y y :area (for [y (range y (+ y circle-radius))
x (range x (+ x circle-radius))] [x y])}))
Since we will be moving circles around the screen, we begin by defining a circle, x and y represent the upper left corner of the circle, area contains a list of coordinates that circle occupies on the screen.
(defn capture-image [vis]
(.read vis)
(let [raw (.pixels vis)]
(doto vis
(.absDiff)
(.convert OpenCV/GRAY)
(.blur OpenCV/BLUR 3)
(.threshold 20)
(.remember))
{:raw raw :diff (.pixels vis)}))
We capture a frame from the camera, save a copy of the image as raw, calculate the difference between the current image and the previous one, keeping only parts of the image where there is movement, convert it to grey scale and apply blur on it to remove camera noise, after running it through the threshold filter resulting image will contain white where there is movement black everywhere else.

(defn white-pixel-count [circle pixels]
(reduce (fn[h v]
(let [x (first v) y (second v)
pix (nth pixels (+ x (* y width)))
blue (bit-and pix 0x000000ff)]
(if (= blue 255) (inc h) h))) 0 (:area circle)))
(defn collision? [circle pixels]
(let [white (white-pixel-count circle pixels)]
(cond (zero? white) false
(> (/ 1 (/ (count (:area circle)) white)) 0.2) true
:else false)))
Detecting collision works by counting the number of white pixels under the circle, if more than 20% of the pixels under the circle contains white, it indicates movement.
(defn validate-circles [circles pixels]
(reduce (fn[h c]
(if (collision? c pixels)
(conj h (create-circle))
(conj h c))) [] @circles))
(defn capture-action [vis panel image circles]
(proxy [ActionListener] []
(actionPerformed
[e]
(let [capture (capture-image vis)]
(dosync (ref-set image capture)
(ref-set circles (validate-circles circles (:diff capture)))))
(.repaint panel))))
With every tick of the timer, we'll iterate over the circles on the screen, checking for collision, if there is collision replace that circle with a new one and repaint the panel to reflect changes.
This covers the meat of the code, I have skipped some boiler plate code such as setting up OpenCV or building images which I already covered here. If you end up making anything cool with it, please leave a comment with a link. I'd love to see it.
Hilbert Curve
16 Jan 2010
The other day, I came across this, a visualization of the Internet address space. Where they ping all the IP addresses in the IP v4 space and plot a table depending on the response from the server, they draw the graph using a fractal called a Hilbert Curve, following uses my turtle graphics implementation to draw the curve.

(ns hilbert
(:use :reload-all turtle))
(def size 10)
(def width 330)
(def height 330)
(defn hilbert [turtle level angle]
(if (> level 0)
(doto turtle
(right angle)
(hilbert (- level 1) (- angle))
(forward size)
(left angle)
(hilbert (- level 1) angle)
(forward size)
(hilbert (- level 1) angle)
(left angle)
(forward size)
(hilbert (- level 1) (- angle))
(right angle))))
(let [turtle (turtle width height)]
(doto turtle
(pen-up)
(go (- 10 (/ width 2)) (- 10 (/ height 2)))
(pen-down)
(hilbert 5 90)
(show)))
Fun with Clojure, OpenCV and Face Detection
12 Jan 2010
I have been meaning to play with OpenCV for a while now, the other night, I had some time to kill so I decided to play with it. OpenCV is a computer vision library originally developed by Intel. It focuses mainly on real-time image processing. I assumed by now there are a lot of Java libraries for OpenCV but as it turns out there is only one, and it is a Processing library. It works with Java out of the box but for Clojure it takes a little more effort.

Grab the OpenCV library, they provide both OpenCV library and Java bindings. Install OpenCV and copy Java bindings to your extensions folder. OpenCV library has two constructors,
OpenCV()
Create a new OpenCV instance.
OpenCV(processing.core.PApplet parent)
Create a new OpenCV instance.
First constructor is for Java and second one is for Processing, if you try to initialize it from Clojure, it will fail trying to locate PApplet class which is distributed with Processing or Arduino IDEs. Install either one of them, grab core.jar that comes with it and copy that to your extensions folder also.
Alex in the comments mentioned, incanter package contains Processing library, you can just grab it from them instead of installing Arduino or Processing. It is located in the deps.zip file.
First we need to configure OpenCV object,
(defn vision []
(doto (OpenCV.)
(.capture width height)
(.cascade OpenCV/CASCADE_FRONTALFACE_ALT)))
We will be capturing from the default webcam and using the FRONTALFACE description file. You can supply your own for detecting other stuff besides faces.
(defn capture-image [vis]
(.read vis)
(let [mis (MemoryImageSource. (.width vis) (.height vis)
(.pixels vis) 0 (.width vis))]
(.createImage (Canvas.) mis)))
Before processing we need to grab a new frame from the camera, we also build a Image from the data we read to be painted on a component.
(defn detect-face [vis]
(.detect vis 1.2 2 OpenCV/HAAR_DO_CANNY_PRUNING 20 20))
Now we are ready to detect object(s) in the current image depending on the current cascade description. detect will return an array of rectangles where faces are detected.
(defn capture-action [vis panel image faces]
(proxy [ActionListener] []
(actionPerformed
[e]
(dosync (ref-set image (capture-image vis))
(ref-set faces (detect-face vis)))
(.repaint panel))))
(defn panel [image faces]
(proxy [JLabel] []
(paint
[g]
(.drawImage g @image 0 0 nil)
(.setColor g Color/red)
(doseq [square @faces]
(.drawRect g
(.x square) (.y square)
(.width square) (.height square))))))
With every tick of the timer, we will grab a new frame from the camera, detect faces in the image then repaint the panel to reflect changes.
(defn key-listener [vis timer]
(proxy [KeyAdapter] []
(keyReleased
[e]
(.stop timer)
(.dispose vis))))
You need to properly dispose of OpenCV object or bad things will happen, you are warned. Just listen for a key event, when the event occurs stop the timer and dispose the OpenCV object.
(defn main []
(let [vis (vision)
image (ref (capture-image vis))
faces (ref (detect-face vis))
panel (panel image faces)
timer (Timer. frame-rate (capture-action vis panel image faces))]
(.start timer)
(doto (JFrame.)
(.add panel)
(.addKeyListener (key-listener vis timer))
(.setSize width height)
(.show))))
When components assembled and timer started, we start detecting faces.
A Simple Turtle Graphics Implementation in Clojure
09 Jan 2010
Turtle graphics is a popular way for introducing programming to kids. It was part of the original Logo programming language developed by Wally Feurzig and Seymour Papert in 1966. Turtle, originally a robotic creature moves on the floor. It takes commands relative to its own position, such as "move forward 10 steps" and "turn left 90 degrees". Turtle also has a pen which may be lowered to the floor so that a trace is left of where it has traveled.
(defn fib [turtle depth]
(forward turtle 30)
(if (> depth 2)
(do
(left turtle 15)
(fib turtle (- depth 1))
(right turtle 30)
(fib turtle (- depth 2))
(left turtle 15)))
(back turtle 30))
(let [turtle (turtle 400 400)]
(pen-up turtle)
(go turtle 0 -100)
(pen-down turtle)
(fib turtle 10)
(show turtle))

(defn fern [turtle size]
(if (> size 4)
(do
(forward turtle (/ size 25))
(left turtle 90) (fern turtle (* size 0.3))
(right turtle 90)
(right turtle 90) (fern turtle (* size 0.3))
(left turtle 90) (fern turtle (* size 0.85))
(back turtle (/ size 25)))))
(let [turtle (turtle 400 400)]
(pen-up turtle)
(go turtle 0 -200)
(pen-down turtle)
(pen-color turtle Color/green)
(fern turtle 1500)
(write turtle "test.png"))

Making Things Move with Clojure
06 Jan 2010
I have added analog write support to clodiuno, which can be used to send a PWM value or control a servo. Servos are the easiest way to play with motor control. Even though they don't turn 360 degrees, they can be used to create mechanisms such as levers and cams. Firmata library supports servos on pins 2 through 13, following code demonstrates how to control a servo using values read from an analog input in this case a potentiometer.
Connections for the board looks like the following, fritzing project is also available here,

Code is made up of two functions, one of which I stole directly from the Arduino libraries,
;;WMath.cpp
(defn map-range [x in-min in-max out-min out-max]
(+ (/ (* (- x in-min) (- out-max out-min)) (- in-max in-min)) out-min))
This is a Clojure version of the Arduino's map function, it will map the number in the in range into out range. Analog read returns a number between 0 and 1023 but the servo expects values between 0 and 179, this will turn the potentiometer reading into an angle for the servo.
(defn servo []
(let [board (arduino "/dev/tty.usbserial-A6008nhh")]
;;allow board to boot
(Thread/sleep 5000)
;;start reading potentiometer
(enable-pin board :analog pot-pin)
;;attach servo
(pin-mode board servo-pin SERVO)
;;
(while
true
(let [pot (analog-read board pot-pin)
angle (int (map-range pot 0 1023 0 179))]
(analog-write board servo-pin angle)))
;;
(close board)))
First we need to tell Firmata to start reporting readings for the potentiometer,
(enable-pin board :analog pot-pin)
Then we set servo pin to SERVO this will make Firmata to attach a servo on that pin,
(pin-mode board servo-pin SERVO)
Now we are ready to read input, map it into an angle, then write it to servo,
(while
true
(let [pot (analog-read board pot-pin)
angle (int (map-range pot 0 1023 0 179))]
(analog-write board servo-pin angle)))
Files
clodiuno - A Clojure API for the Firmata Protocol
03 Jan 2010
Firmata is a protocol and a firmware for Arduino, it allows you to control Arduino via a serial protocol from any language that has serial port support. I had a lot of free time during the holidays so I started to implement the protocol, unfortunately protocol isn't well documented, so it took a while to get a hang of it. For now not every thing is supported, I have implemented digital read/writes and analog read.
You can grab a copy of clodiuno here. Of course no Arduino introduction is complete with out blinking something, below snippet should give you a feel for the API, there are more examples in the examples folder included with the project.
(ns sos
(:use :reload-all clodiuno.core))
(def short-pulse 250)
(def long-pulse 500)
(def letter-delay 1000)
(def letter-s [0 0 0])
(def letter-o [1 1 1])
(defn blink [board time]
(digital-write board 13 HIGH)
(Thread/sleep time)
(digital-write board 13 LOW)
(Thread/sleep time))
(defn blink-letter [board letter]
(doseq [i letter]
(if (= i 0)
(blink board short-pulse)
(blink board long-pulse)))
(Thread/sleep letter-delay))
(defn sos []
(let [board (arduino "/dev/tty.usbserial-A6008nhh")]
;;allow arduino to boot
(Thread/sleep 5000)
(pin-mode board 13 OUTPUT)
(doseq [_ (range 3)]
(blink-letter board letter-s)
(blink-letter board letter-o)
(blink-letter board letter-s))
(close board)))
This will make your Arduino call for help. Result will be similar to the following but with a single LED.