One of the problems in the world of moving robots is the task of figuring out where robot is. One way is to mount a GPS-module on the robot. Simpler solutions might include methods that measure how many rounds the wheels have spun and (with the help of the diameter of the wheels and our friend π) calculate the distance travelled. What if the wheel spins or slides? Then the robot "thinks" it's further along than it actually is.
Andri suggested an alternative; how about using a cheap little device everyone owns and is especially made to measure distances (even in 2 dimensions!). The device referred to is an (optical) mouse. All it does is to measure distances, translate them into coordinates and deliver them to the computer it is attached to. The question we asked ourselves was what if we can somehow circumvent all this logic and read the measurements directly.
All this device does all day long is to measure distances but a heart surgery was needed. By doing that we ended up creating an optical-mouse scanner.
The first thing was to perform a heart-surgery on our mouse and figure out what components it is made of. Upon opening the mouse up we found a microchip with some sort of a serial number which we googled and stumbled upon its datasheet. The datasheet was a pleasent reading and we discovered that this $5 device was quite remarkable; it was equipped with a camera, a microchip and an pattern recognition microchip. The way an optical mouse works is to take a picture (18x18 px) of a 1x1mm surface and compare its pattern with the pattern from the privously taken picture. By calculating the movement of the pattern it's able to figure out how far it has been moved between the two frames. Pretty clever!
By powering the mouse and reading the registers from the microchip through a serial communication line (using the protocol described in the datasheet) we were able to read the measurements. We had succeeded in our original endaevour.
Now armed with the powers to communicate with the mouse what was there to stop us from trying to read the image the optical mouse camera was taking? Answer: Nothing. Reading the datasheet provided us with the necessary knowledge. It is actually quite simple: You just need know that the image is stored as a 18x18 pixels with each pixel being a 8bit grayscale value (0-255). Just read the data serially and compose on the other end. This seemed to work but each frame received was such a small fraction of the surface (1x1mm) we could hardly "see" anything on the picture taken. The solution to that is to combine all the pictures taken and draw them on a canvas related to the coordinates we were reading from the mouse. By doing that we ended up creating an optical-mouse scanner.
Reads: iðnaðarverkfræði (industrial engineering)
On our mission to learn Robotics an opportunity presented it self; a line-following competition hosted by IEEE Iceland, November 22nd, 2009. What was known beforehand was this:


On the front is the Arduino board with connections to the motor controller which was used to control the motors. The controller can pulse the motors to decrease the 9V from the batteries and change the direction of the motors. This way (and with the help of the steel ball on the front rotating in all directions) the the racer could make any kind of turns and in fact turn on the spot - making it very maneuverable. A plate with LEDs was mounted under the racer with light sensors. The light sensors measure the light reflected from the surface under the racer and therefore sensing where the 25mm black track was.

We assigned the sensors a value from -3 (the sensor second furthest to the left) to +3 (the sensor second furthest to the right). As can be seen from the picture there are 8 sensors but because the Arduino board only has 6 analog inputs and we were unable to connect a comparator to connect the remaining 2 to the digital inputs of the board we left the two sensors on the edges unused.
Armed with a way to control the motors and measure the location of the track the only thing left was to create a steering controller. After some pondering we decided to go with a PID controller which I implemented in C++. The aim of the PID controller was to keep the average of the values of the sensors equal to zero. The code for the whole project can be found here.
When we arrived it was announced that the track was a modeled after the F1 Suzuka track in Japan. After a few test rounds where we tweaked the parameters of our racers we were ready to go.

Four teams participated in the competition and we were the first team to race. We decided to be on the safe side and we reduced the speed to be sure to finish the track. And we did. Our time 29 seconds. None of the other teams made a successful lap. As we had the lead we decided to try for a faster lap. This time we however we went too fast into one of the turns and the racer lost control. Fortunately none of the other teams made it either and we were declared the winners with 10 points and a time of 29 seconds :)
I have been dreading porting my Blog application from HAppS to Happstack for a long time now. It is however apparent that HAppS is dying and Happstack (a fork of HAppS designed to take things further) was the only way to roll.
... a refreshingly innovative web application server written in Haskell. Leveraging the MACID state system, Happstack offers robust and scalable data access without the headache of managing a traditional RDBMS such as MySQL.
The RELEASE_NOTES file had some guidelines for porting existing applications to Happstack. In my case it turned out to be really easy:
sudo cabal install happstack
find . -type f -name '*.hs' -exec sed -i.bak 's/HAppS/Happstack/g' {} \;
find . -type f -name '*.hs' -exec sed -i.bak \
's/unServerPartT/runServerPartT/g' {} \;
> let peer = case addr of
> (S.SockAddrInet _ ha) -> showHostAddress ha
> (S.SockAddrInet6 _ _ ha _) -> showHostAddress6 ha
> _ -> error "Unsupported socket"
> return (h, peer, p)
name: gisliblogversion: 0.0synopsis: Personal websitedescription:category: Weblicense: BSD3license-file: LICENSEauthor: Gísli Kristjánssonmaintainer: gislik hamstur.isbuild-depends: base,feed,nano-md5,hscolour,json,curl,HStringTemplate,happstackbuild-type: Simplehs-source-dirs: srcexecutable: gisli.hamstur.ismain-is: src/Main.hsghc-options: -isrc
uriRest :: Monad m => (String -> ServerPartT m a) -> ServerPartT m a
uriRest handle = withRequest $ \rq ->
unServerPartT (handle (rqURL rq)) rq
uriRest :: (ServerMonad m, Monad m) => (String -> m a) -> m a
uriRest handle = askRq >>= handle . rqURL
Mechatronics is an interest that my colleague Andri and I share. For some months we have been trying to initiate a Mechatronics project but for some reason we never seem to be able to start even though we're both pretty motivated.
Armed with the new coordinates it was relatively easy to have a computer draw up what our Wall-E «saw»
Earlier this summer we met up and did a warm-up exercise. The purpose of the exercise was to get familiarized with the newly bought analog sonar. We hooked the sonar to a stepper motor that with the help of a BASIC Stamp Microcontroller turned the sonar 90° while measuring the distance to the next object. This way we got a reading in the Polar-plane which was then projected onto the XY-plane. Armed with the new coordinates it was relatively easy to have a computer draw up what our Wall-E «saw». On the right is our version of Wall-E.

Last week we decided to switch to the ATmega microcontroller on the Arduino Duemilanove microcontroller board.

The Arduino Duemilanove ("2009") is a microcontroller board based on the ATmega168 (datasheet) or ATmega328 (datasheet). It has 14 digital input/output pins (of which 6 can be used as PWM outputs), 6 analog inputs, a 16 MHz crystal oscillator, a USB connection, a power jack, an ICSP header, and a reset button. It contains everything needed to support the microcontroller; simply connect it to a computer with a USB cable or power it with a AC-to-DC adapter or battery to get started
Arduino can sense the environment by receiving input from a variety of sensors and can affect its surroundings by controlling lights, motors, and other actuators. The microcontroller on the board is programmed using the Arduino programming language (based on Wiring) and the Arduino development environment (based on Processing). Arduino projects can be stand-alone or they can communicate with software on running on a computer (e.g. Flash, Processing, MaxMSP). We intend to control the Arduino with a Beagle Board.
What our little Mechatron is supposed to do in the end is very unclear. We are mainly going to have loads of fun while learning the ropes of mechatronic. This week we'll receive two (1, 2) books to start our journey. As we progress I'll be posting the results on this blog.
My brother has been asking me for a new feature for some time now. It's a simple video feature where instead of showing a picture when clicked on a video begins to play. I had been holding this project off for a while because I knew that model migration would probably be a hazzle.
I can recommend the LongTail FLV video player. It can handle FLV, MP4, MP3, AAC, JPG, PNG and GIF files. It also supports RTMP, HTTP, live streaming, various playlists formats, a wide range of settings and an extensive javascript API.
What exactly is model migration? Well, when you model your data you come up with something like this:
data Photo = Photo {
photoName :: String
,photoText :: String
,photoDate :: AppDate
,photoCategory :: Maybe CategoryID
,photoCategoryCover :: Bool -- Calculated
,photoCover :: Bool -- Calculated
,photoSeriesCover :: Bool -- Calculated
,photoOrder :: Int
,photoCategoryOrder :: Int
,photoSeriesOrder :: Int -- Calculated
,photoCreated :: AppDate
,photoModified :: Maybe AppDate
} deriving (Show, Read, Eq, Data, Typeable)
When you start to use your model HAppS records your data into this structure in a binary form. Now let's say that you need to add a field for the name of the video to be played instead of showing the picture you get something like this:
data Photo = Photo {
photoName :: String
,photoText :: String
,photoDate :: AppDate
,photoCategory :: Maybe CategoryID
,photoCategoryCover :: Bool -- Calculated
,photoCover :: Bool -- Calculated
,photoSeriesCover :: Bool -- Calculated
,photoOrder :: Int
,photoCategoryOrder :: Int
,photoSeriesOrder :: Int -- Calculated
,photoVideo :: Maybe String -- THE ONLY DIFFERENCE!
,photoCreated :: AppDate
,photoModified :: Maybe AppDate
} deriving (Show, Read, Eq, Data, Typeable)
Notice that I've only added the photoVideo field. The problem is however that when HAppS tries to read in the old structure it does not know how to map it to the new structure (model). That's when you need to worry about model migration.
Fortunatelly it's super easy in HAppS. In my case the Photo model was in a module called Model.Photo. To migrate you just have to execute the following steps
import qualified Model.Photo1 as P1
instance Migrate P1.Photo Photo where
migrate p1 = Photo {
photoName = (P1.photoName p1)
,photoText = (P1.photoText p1)
,photoDate = (P1.photoDate p1)
,photoCategory = (P1.photoCategory p1)
,photoCategoryCover = (P1.photoCategoryCover p1)
,photoCover = (P1.photoCover p1)
,photoSeriesCover = (P1.photoSeriesCover p1)
,photoOrder = (P1.photoOrder p1)
,photoCategoryOrder = (P1.photoCategoryOrder p1)
,photoSeriesOrder = (P1.photoSeriesOrder p1)
,photoVideo = Nothing
,photoCreated = (P1.photoCreated p1)
,photoModified = (P1.photoModified p1)
}
instance Version Photo where
mode = extension 2 (Proxy :: Proxy P1.Photo)
When HAppS starts up again it knows exactly how to transform the old structure into the new one.
Happy migration!
As mentioned in my tweed my brother's online photo album went live last Thursday. Since then I've been trying to think not so much about it because this project had started to consume my brain leaving little space for anything else (including sleeping). I'm happy with the responses he's been getting over the last couple of days - and the most important thing; he's happy.
Readers of this blog know by now that this website was entirely written in Haskell/HAppS and I loved writing it. In this post I'll attempt to discuss some of the more interesting parts of the site and show you a screen cast of the administrative panel.
Because I'm using HAppS there is no need for a database. HAppS-State simply persist my native data structure. The photos are represented as maps of photos, like this:
type Photos = Map PhotoID Photo
type PhotoID = String
data Photo = Photo {
photoName :: String
,photoText :: String
,photoDate :: AppDate
,photoCategory :: Maybe CategoryID
,photoCategoryCover :: Bool -- Calculated
,photoCover :: Bool -- Calculated
,photoSeriesCover :: Bool -- Calculated
,photoOrder :: Int
,photoCategoryOrder :: Int
,photoSeriesOrder :: Int -- Calculated
,photoCreated :: AppDate
,photoModified :: Maybe AppDate
} deriving (Show, Read, Eq, Data, Typeable)
Some of the fields are have a Calculated comment. These fields do not depend on being persisted (this is of course not enforced by HAppS in any way) but they are rather calculated when needed and handed over to the templates where they control how the photo is rendered.
To warm up let's take a look at one of the simplest controller action (Controller.Photo.list):
list :: WebT IO LayoutResponse
list = liftIO $ do
env <- appEnv :: IO (AppEnv String String)
photos <- query ListPhotos
photo <- liftM (pidToPhoto photos) $ query GetCoverPhoto
photoTemplate <- liftM (attr "photo" photo) $ parseTemplate env "photos_show"
returnLayout Nothing (attrSession "body" photoTemplate)
Normally a controller action would have a type of WebT IO Response but I've created the LayoutResponse type to be able to wrap the master layout around the template (in this case photos_show). The variable photos has the the Photos (a map of Photo) and GetCoverPhoto returns the Photo ID (pid) of the cover photo which is then looked up with the function pidToPhoto in the photos map. The cover photo then gets assigned to the photo template variable. When the photo template has been parsed it self gets assigned to the body template variable which is returned from the controller action and handed to the wrapLayout function which purpose is to transform LayoutResponse to Response. This is a very common practice in my code.
One of the more interesting controller actions is the one serving the photos. When a photo is requested the request gets handed to the Photo controller. If the photo does exist it is served directly but if it does not exist it is resized according to the directory name it's contained in, i.e. h540 (meaning fix the height at 540 pixels), provided that the requested size is allowed (appears in sizes.txt)
legalSizes :: IO [String]
legalSizes = liftM lines (readFile "sizes.txt")
serveFile' :: FilePath -> [FilePath] -> FilePath -> ServerPartT IO Response
serveFile' orgsDir _ dir = let resize size f f' im = do
(w, h) <- imageSize im
let (fix, l) = splitAt 1 size
let l' = read l :: Int
let (w', h') = if fix == "w"
then (l', (l'*h)`div`w)
else ((l'*w)`div`h, l')
let geometry = (P.show w')++"x"++(P.show h')
status <- liftIO $ rawSystem "convert"
["-geometry"
,geometry
,"-quality"
,(P.show quality)
,f
,f']
case status of
ExitFailure code -> fail.P.show $ code
ExitSuccess -> return ()
in
let resizePhoto size f f' = do
case map toLower (takeExtension f) of
".jpg" -> loadJpegFile f >>= resize size f f'
".png" -> loadPngFile f >>= resize size f f'
".gif" -> loadGifFile f >>= resize size f f'
in
withRequest $ \req -> do
currentDir <- liftIO getCurrentDirectory
let (year:size:pid:_) = rqPaths req
let file = joinPath [currentDir, orgsDir, year, pid]
let file' = joinPath [currentDir, dir, drop 1.rqUri $ req]
doesExist <- liftIO.doesFileExist $ file'
sizes <- liftIO $ legalSizes
let fixedRqPaths = map (drop 1).groupBy (\_ y -> y/='/') $ rqUri req
let serveFile'' = do
modifyResponse serveHeaders
unServerPartT (fileServe [] dir) $ req { rqPaths=fixedRqPaths }
if doesExist
then serveFile''
else if size `elem` sizes
then do
liftIO $ createDirectoryIfMissing True (takeDirectory file')
liftIO $ resizePhoto size file file'
serveFile''
else noHandle
As you can see I spawn convert from ImageMagick in a different process to resize my photos. There are bindings to ImageMagick available for Haskell but was unable to install them. Initially I wanted to go for a much simpler option and use the GD library which is a much simpler library and its bindings seemed much simpler. The problem was however that the GD library decreased the quality of the photo.
GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> :m +Graphics.GD Prelude Graphics.GD> loadJpegFile "405ba7c1fc3aefcbe3cf4471ef1b781f.jpg" >>= resizeImage 600 400 >>= saveJpegFile 100 "gd-405ba7c1fc3aefcbe3cf4471ef1b781f.jpg"

$ mogrify -geometry 600x400 405ba7c1fc3aefcbe3cf4471ef1b781f.jpg im-405ba7c1fc3aefcbe3cf4471ef1b781f.jpg

The second is much richer in colors and identical to the source while the first one created with GD library is brighter and generally lower in quality. This was a big surprise and a let-down but I'll just be using ImageMagick in the future. I wish someone would update the bindings though. For the purpose of creating small images containing only text the GD library seemed sufficient:
newImage ((width rect)-1, height'+1)
>>= fillImage (rgb 0 0 0)
>>= drawString "fonts/current.otf" size 0 (x,y) title
(rgb (v r1 r2) (v g1 g2) (v b1 b2))
>>= savePngFile filename
Lastly I'd like to point out how one handles files submitted through HTML forms. The trick is to use inputFilename and inputValue like this:
handleData = do
photo <- lookInput "photo"
cid <- look "cid" `mplus` return ""
series <- look "series" `mplus` return ""
let Just name = inputFilename photo `mplus` Just ""
let contents = inputValue photo
return (name, contents, cid, series)
I hope this post is of use for someone and if you've some questions please leave a comment.
... but there's no activity on your blog you may say. Well I decided to do my brother a favor. He is a professional photographer working for a photo gallery called Magg but with his own clientele. Now facing changes in the photographic scene as the recession begins to creep in he wanted to strengthen his own professional presence. The vehicle for such a requirement was an online photo gallery (due to open this week) with some of his more artistic images.
Initially I was going to create the gallery with Python and SQLite but I found myself always going back to hacking on my bloging platform. That was until I found the reason why; I had so much fun programming in Haskell. Armed with this new knowledge I decided to jump into the deeper end of the pool and rewrite (what little I had already done in Python) in Haskell. I was able to re-use much of my work from the bloging platform experience but this time around further investigation was needed to fulfill some of the requirements, such as uploading (multiple) photos, rescaling them and soforth. I will happily share my solution with you in coming blog posts although naturally I cannot give you access to the administrative side of the gallery. Instead I'll post some photos with some explanation or even create a screen cast of the admin part.
With very few photos in the system it does perform remarkably well and I am very interested in what the site will feel like with a few hundreds or even thousands of photos in there.
The next steps for my blog will be to Tag-enable it. I am thinking about extending the Tags into Series where each blog in the Series will have links to the other posts in the series in a chronological order. This way I'll be able to group a number of blog posts and present them as a whole.
P.S. As you have duly noticed I've begun to blog in English (at least where the topic is Haskell). I hope this goes well with everyone :)
Þó tilgangurinn með þessu bloggi sé að fá útrás fyrir nördaskap, með því að læra Haskell, er hann ekki síður að stuðla að umræðu áhugafólks um Haskell og því ákvað ég að gera örlitla könnun á mögulegum markhópi fyrir svona blogg. Mér til mikilla vonbrigða virðist enginn á Íslandi hafa áhuga á þessu forritunarmáli því þetta eru niðurstöðurnar fyrir utan þær síður sem ég átti:
Fyrir utan Arnar þá held ég að Haskell-samfélagið á Íslandi sé ekki til og ég hef því og mun því tala fyrir daufum eyrum hérna á þessu bloggi.
Á síðustu vikum hef ég þó tekið eftir Arnari nokkrum Birgissyni (syni Birgis Þórs Bragasonar) sem ég man eftir úr Verzló. Hann hefur verið að skrifa um Haskell erlendis, bæði á póstlista og einnig rannsóknargreinar. Það er svona spurning hvort maður eigi að setja sig í samband við hann.
Fyrir utan Arnar þá held ég að Haskell-samfélagið á Íslandi sé ekki til og ég hef því og mun því tala fyrir daufum eyrum hérna á þessu bloggi. Þess vegna er ég að velta því fyrir mér að gera tvennt; annars vegar útvíkka umfjöllunarefni bloggsins og hins vegar skrifa á ensku (til þess að ná til stærri hóps þegar umfjöllunarefnið er Haskell). Ég er með nokkrar hugmyndir sem ég hefði áhuga á að skrifa um eftir að þetta bloggkerfi er komið vel á koppinn því mig langar, seinna meir, til þess að skoða betur hljóð og mynd og ýmislegt sem því tengist ásamt pælingum úr fjármálageiranum. Hitt er svo annað að ég er búinn að gera það að forgangsverkefni fyrir þetta blogg að búa til Atom-straum, brenna bloggið með Feedburner.com og fæða því yfir í Twitter. Það má því búast við því að næsta færsla um bloggið verði á ensku.
Í fyrirsögninni er ég að vísa í vörðu í merkingunni Milestone. Loksins kom að því að þessi vefur er orðinn HAppS/Haskell-væddur. Áður var þessi vefur statískur en dýnamíkin byggði á öðrum þjónustum, s.s. Google Notebook. JavaScript var notað til þess að brúa bilið á milli þjónustanna og vefsíðunnar. Ástæðurnar fyrir þessu fyrirkomulagi voru 2.
Þegar ég fór að skoða HAppS var mér tjáð að ekki væri heppilegt að byrja á þeim endanum. Eftir á að hyggja er ég hjartanlega sammála því að byrja einhvers staðar annars staðar. Því þrátt fyrir að hafa fengið þessa vísbendingu tók það mig um 3 tilraunir til þess að komast inn í Haskell-hugsunarháttinn.

Bloggið var sá hluti sem ég ákvað að byrja á og til þess að koma því í kring þurfti ég að smíða notenda- og setukerfi (user and session management system). Með OpenID er hægt að láta aðra vefi, eins og Google, Yahoo! og Facebook, halda utan um notandanafnið og lykilorðið. Í seinni póstum ætla ég að fjalla betur um hvernig OpenID virkar. Einnig ætla ég í seinni póstum að ræða það sem ég hef lært og vísa í kóðann minn sem dæmi. Í þessum pósti langar mig þó til þess að ræða uppsetninguna í grófum dráttum:

Þegar beiðni um vefsíðu kemur inn tekur HAppS á móti beiðninni og áframsendir hana á rétta stýru (controller). Stýran hefur síðan samband við stöðuvélina, HAppS-State, og gerir annað hvort fyrirspurnir á henni eða breytingar. Að lokum eru gögnin (model) úr stöðuvélinni send fram í birtingarlagið (view) en þar tekur HStringTemplate við þeim og breytir í HTML.
Næstu skref eru að bæta við stuðningi fyrir tög, athugasemdir og TrackBack ásamt því að tengja eitthvert myndakerfi við bloggið en ég ætla aðeins að bíða með það þar sem ég ætla að einbeita mér að öðru verkefni fyrir Baldur bróður.
Af einhverri ástæðu er ég andvaka núna en það er mjög skrítið í ljósi þess að ég var í nuddi fyrr í dag og nuddarinn tók svo vel á mér að ég var við það að sofna um kvöldmatarleytið. Núna hins vegar er ég glaðvakandi.
Mér fannst því að ég gæti notað tímann og hent einni stuttri færslu hér inn (skammast mín fyrir að það séu rúmir 3 mánuðir liðnir frá síðustu færslu). Síðustu vikur hefur þó talsvert verið að stúderaHaskell með það að leiðarljósi að skrifa meira af þessari síðu í því. Núna í desember kemur út bókin Real World Haskell, útgefin af O'Reilly, sem hægt er að lesa ókeypis í heilu lagi á netinu. Ég er búinn að lesa megnið af henni og verð ég að hrósa bæði þessu framtaki og líka gæði bókarinnar. Loksins er ég farinn að setja hlutina í samhengi og strax eftir að ég var búinn að lesa hana tókst mér að búa til græju sem tekur CSV-skjal með nöfnum og heimilisföngum, flettir þeim upp á ja.is og skilar símanúmerinu til baka inn í nýja CSV-skrá. Fram að þeim tímapunkti gat ég eingöngu skrifað forrit sem voru svona u.þ.b. 2-5 línur.
Eftir að vera kominn með örlítið meira sjálfstraust ákvað ég að líta á HAppS á ný. Við gúglun (er hægt að nota þetta orð svona?) fann ég síðuna happstutorial.com sem er eins og lénið gefur til kynna leiðbeiningasíða sem fer skref fyrir skref með manni í gegnum HAppS. Á síðunni á þó eftir að klára þann hluta sem snýr að HAppS.State en það er sá hluti sem geymir gögnin. Mér til mikillar ánægju tók ég eftir því þegar ég setti leiðbeiningarnar upp á tölvunni minni voru þessir hlutar klárir og ég gat fræðst betur en nokkurn tíman áður um það hvernig maður geymir gögn. Ennfremur útskýra þessar leiðbeiningar hvernig maður getur notað HStringTemplate sem byggir á hönnun StringTemplate fyrir Java, C# og Python. Þessi síða hefur líka að geyma hagnýtar upplýsingar um forritun í HAppS.
Ég er því kominn vel af stað með það að flytja bloggið mitt úr venjulegri textaskrá yfir í dýnamíska útgáfu, skrifaða fyrir HAppS. Á næstu vikum mun ég skrifa um það sem ég læri og verður næsti póstur því um setustjórnun (session management) og hvernig hægt er að útfæra slíkt í Haskell.
Þegar ég var staddur úti á Spáni í fallhlífastökkinu (sjá fyrri færslu) þá tók ég eftir því að strax á fyrsta degi voru allir búnir að "húkka sér saman" á Facebook (FB). Ég hef í nokkurn tíma haft illan bifur á öllu svona. Ég held að það hafi verið MySpace sem eyðilagi þetta fyrir mér - þvílíkt kaos!
En þegar ég áttaði mig á því að mig langaði til þess að halda sambandi við þennan hóp og til þess að vera alveg sannleikanum sannkvæmur þá var ég ekki að fara hringja í þau (og sennilega ekki einu sinni að fara að senda þeim tölvupóst). Ég ákvað því að leggja FB-hrokann minn til hliðar og skrá mig inn.
Og, verð að viðurkenna að FB er ekki svo galið eftir allt saman.
Til þess að gera langa sögu stutta er ég gjörsamlega fallinn. Og, verð að viðurkenna að FB er ekki svo galið eftir allt saman. Maður er nú farinn að gera allt þetta helsta; "adda vinum", skrifa á veggi og áður en ég veit af verð ég farinn að senda sýndarbjóra! Reyndar held ég að það sé langt (ef einhvern tímann) í að ég fari að senda sýndarbjóra. Þegar ég hugsa um það þá er það sennilega sá þáttur sem pirrar mig mest.
Reyndar sé ég núna að þetta er frábær leið til þess að halda sambandi við fólk (og þá sérstaklega fólk sem maður hittir ekki á öllu jöfnu). Ég er t.d. búinn að finna týnda æskufélaga, bekkjarfélaga og aðra sem ég var búinn að missa af.
Það sem mér finnst hins vegar lang mest spennandi er FB-þróunarumhverfið sjálft. Ég hef nefnilega lengi gengið með hugmynd í maganum en hef einhvern veginn aldrei komið mér í að framkvæma hana vegna þess að það til þess að geta framkvæmt hana þarf ég að gera heil ósköp áður. Það magnaða er að FB eru þessi heilu ósköð og ég get einbeitt mér að því að framkvæma hugmyndina sjálfa.
Það sem er líka spennandi við að þróa þetta á FB er fjöldi notenda. Það er hægt að koma hugmyndum í dreifingu á mjög skömmum tíma til mjög margra og ef mér tekst vel til ætti að vera hægt að hafa tekjur af þessu.
Planið er því að skoða FB-þróunarumhverfið betur. Ég er búinn að vera að forrita ákveðinn feril (upphaf viðskipta) í vinnunni upp á síðkastið. Til þess hef ég verið að nota Python og er gjörsamlega ástfanginn af því forritunarmáli. Það virkar eins og hugur manns. Hins vegar hef ég verið að velta því fyrir mér hvort það sé heppilegt sem FB-forritunarmál og er eiginlega kominn að þeirri niðurstöðu að svo sé ekki vegna álags á FB-hugbúnað. Haskell er ekki með allt of góðan stuðning við vefforritun (og það tekur lengri tíma að koma sér inn í það en ég hef). Ég hef því verið að horfa til Erlang sem virðist vera kjörið í þessum aðstæðum.
Ég skrifa meira um þessar pælingar þegar þær eru komnar lengra á veg.
Fyrir tveimur vikum ákvað ég að fara til Spánar og stökkva í fallhlíf. Viku síðar var ég staddur í litlum bæ, nánar tiltekið í Ocaña sem er 30 km suður af Madríd, eftir að hafa flogið til Alicante og keyrt þaðan. Fyrsta daginn var ég settur í skóla og þurfti ég, ásamt bretanum Chris sem ég kynntist ágætlega, að læra allt sem hægt er að hugsa sér áður en maður stekkur út. Næsta dag hófst ballið. Þá var sett á mig fallhlíf og farið upp í 12.500 fet (c.a. 4 km). Nokkrum sekúndum síðar var ég kominn á 200 km hraða (niður á við :). Kennarinn minn, Andy, og aðstoðarkennarinn, Mike, (sem stökk fyrstu 3 stökkin með okkur) stukku með mér og sáu til þess að allt væri eftir bókinni. Þvílíkur tryllir! Á meðan maður er að ná lokahraða (um 120 mílna hraði) þá líður manni eins og maður sé að falla. Þessi tilfinning er allsráðandi fyrstu 10 sekúndurnar. Þegar maður hefur náð lokahraða er þetta meira eins og að fljóta og hefur maður um 1 mínútu í loftinu áður en maður þarf að opna fallhlífina.
Námskeiðið byggist upp á 7 stigum og ef maður þarf ekki að endurtaka neitt stig þá eru þetta 7 stökk. Ég henti video-i af stökkunum 7 inn á YouTube en mig langar til þess að klippa þetta betur saman.
Eftir góða daga var sest niður í bjór og góðum mat í bænum Aranjuez. Ég held að það sé alveg víst að þetta er eitthvað sem mig langar til þess að gera næstu árin.
Ég setti inn nokkrar myndir úr ferðinni.
Ég breytti slóðunum á þessari síðu á þann veg að nú hægt að nota back-hnappinn. Ég er búinn að finna nokkrar spennandi síður um HAppS en af einhverri ástæðu er SearchPath hætt að virka hjá mér svo ég er pínu strand. Ég sé að einhver er að vinna í að fá það í lag svo ég ætla að reyna að vera þolinmóður.
Markaðir í dag hrundu, krónan í frjálsu falli og Bear Stearns fór á hausinn. Þetta eru svakalegir tímar!
Stutt skilaboð. Á miðvikudaginn síðasta réð ég mig í vinnu hjá H.F. Verðbréfum og starfa nú þar sem miðlari. Þar sem ég ætla að reyna að halda þessu bloggi hnitmiðuðu á forritun og fjármál þá ætla ég ekki að hafa þetta lengra í bili.
Vefur vinahópsins hefur legið í dvala í um 2 ár eftir að gamli vefurinn var lagður niður. Við skrifuðum annan fyrir árshátíð Skúla í fyrir í Ruby on Rails en þar sem við höfðum enga vél til að keyra hann fór hann aldrei í loftið. Núna þegar nýi þjónninn er kominn í gagnið kemur í ljós aðRails hefur breyst það mikið síðan í fyrra að kóðinn okkar keyrir ekki. Talsvert svekkelsi!
Ég veit ekki hvað ég er búinn að skrifa mörg vefkerfi og tilhugsunin um að skrifa enn eitt er mér alls ekki kær. Mér datt því í hug að keyra vefinn á einhverju CMS-kerfanna. Það kemur hins vegar alltaf að því að maður hefur áhuga á því að fara örlítið út fyrir mynstur kerfisins og þá verður líf manns skelfilegt - flókið og leiðinlegt. Ég einsetti mér því að skrifa eins lítið vefkerfi og ég mögulega kemst upp með.
web.py er minimalískt umhverfi fyrir Python og fellur því eins og flís við rass að forsendunum. Ég er líka kominn með leiða á því að módela gögn í gagnagrunni og því datt ég inn á nýja tegund af gagnagrunni, svokallaðan skjalagagnagrunn (e. document-centric database) sem heitir CouchDB. Haft er samband við grunninn yfir HTTP-staðalinn og skilar grunnurinn gögnum á JSON-formi. Frekar spennandi!
Í dag eyddi ég talsverðum tíma í síðuna. Hér er hægt að nefna að verkefnasíðan er komin vel af stað. Eingöngu er þó um texta að ræða en þegar ég verð kominn með smá textastubb um öll verkin ætla ég að bæta við textann og hengja myndir með verkefnunum.
Upplýsingasíðan var líka tekin í gegn og nýtt efni sett inn. Ég er orðinn nokkuð ánægður með efnið. Fyrir nyrðina þarna úti bjó ég líka til nýja síðu sem lýsir ástandi vefsins í það og það skiptið.
Svo fyrir þá sem höfðu séð bloggið taka þeir væntanlega eftir að hér hefur einnig ýmislegt verið gert en mestu breytingarnar eru að bloggið er komið inn í aðalútlitið í stað þess að vera bara textaskjal.
Heilt yfir er þessi æfing með að tengja Google Notebook og textaskjöl inn á vefsíðuna meðJavaScript. Stór galli er þó að Back-hnappurinn virkar ekki. Þetta lagast þó állt sjálfkrafa þegarHaskell fer að þjóna þessu efni.
Eftir að hafa skrifað síðasta póst hlóð ég niður Colloquy, sem er IRC-biðlari fyrir Mac OS X. Þar skráði ég mig á rásina #happs og byrjaði að spjalla. Til að byrja með svaraði mér enginn en það var e.t.v. eðlilegt í ljósi þess að það var mið nótt. Daginn eftir lifnaði þó aðeins við mönnum á rásinni. Menn voru almennt sammála því að ekki væri heppilegt að byrja Haskell-upplifunina á því að stúdera HAppS. Þetta voru að sjálfsögðu gríðarleg vonbrigði fyrir mig enda hafði ég gert mér vonir um að læra málið og jafnframt koma undir mig fótunum á vefheimili mínu (gisli.hamstur.is). Hins vegar get ég vel skilið þeirra rök og hef því hugsað mér að gera eftirfarandi:
Þess vegna er þetta blogg núna eingöngu texti.
Koma síðunni í fallegri búning, þrátt fyrir að allt verði statískt.
Áður en ég fer að fikta mikið í HAppS.
Smám saman bætist í þekkinguna þannig að ég geti fegrað og forritað kerfi á bak við bloggið. Þetta verður því aðeins lengra ferli en ég var að vonast til.
Góðu fréttirnar eru hins vegar þær að ég náði að koma HAppS-þjóni upp og tókst að láta beiðnir á rótina áframsendast á bloggið mitt, þ.e. þetta textaskjal. Þetta gekk ekki vandræðalaust fyrir sig og ef til vill er þetta óþarflega flókið hjá mér. Hægt er að sjá kóðann fyrir þjóninn hér.
Það hefur runnið upp fyrir mér síðustu daga að lærdómskúrvan fyrir vefforritun í Haskell er mjög brött. Það er lítið til af skrifuðu efni. Mér sýnist þó eftir þessa rannsóknarvinnu að þrjár leiðir séu helst færar:
Kostur: Ekki þarf að þýða Haskell kóðann.
Galli: Hægvirkt
Kostur: Getur keyrt á þekktum vefþjónum eins og Apache og LigHTTP.
Galli: Þarf að endurræsa vefþjóninn til þess að breytingar taki gildi.
Kostur: Margir, sjá umfjöllun hér að neðan
Galli: Nánst engar upplýsingar um HAppS
Þar sem ég er á höttunum eftir algjörlega nýrri hugsun (eins og fram kemur í fyrstu færslunni) ákvað ég að velja síðustu leiðina, þ.e. nota HAppS. Ég eyddi um klukkutíma í að horfa á fyrirlesturum HAppS sem Alex Jacobson, höfundur HAppS, hélt í október á síðasta ári. Þar sem ég hef lengi verið í vefforritun og sjálfur með hugmyndir um það hvernig mér finnist hluturnir eiga vera gerðir kom mér skemmtilega á óvart hvað Alex hafði skemmtilega og í raun mjög sambærilega sýn.
Í venjulegu vefumhverfi, oft nefnt N-laga umhverfi, skiptist umhverfið venjulega í þrjú lög:
Gögn eru í flestum tilfellum geymd í gagnagrunnum en til þess að gögnin séu nothæf þarf að módela gögnin í forritunarmálinu sem notað er.
Hér er virkni vefjarins ákveðin.
Þegar aðgerðarlagið er búið að vinna með gagnamódelin eru þau áframsend í þetta lag. Venjulega er það hér sem blanda af forritunarmáli og HTMLi skilar niðurstöðunum til vafrans.
Gallinn við þessa uppsetningu er oft á tíðum sá að mikil vinna er fólgin í því að koma gögnunum úr gagnagrunninum og í strúktúr sem nýtist í forritunarmálinu. Einnig getur verið erfitt að skala þetta umhverfi. Ég er því opinn fyrir þeim aðferðum sem HAppS leggur til:
Gögnin eru módeleruð frá upphafi í Haskell og litið er á vefinn sem stöðuvél. Staðan hverju sinni er geymd í minni en skrifuð út í svokallaða logga. Þannig getur þjónninn spólað í gegnum alla loggana til þess að flytja kerfið í síðustu stöðu ef endurræsa þarf þjóninn. Þetta hefur verið þekkt sem Prevayler-mynstrið. Til þess að koma í veg fyrir að þjónninn þurfi að lesa loggana frá örófi alda skrifar hann út millistöður (e. Check point) með reglulegu millibili. Eingöngu þarf þá að lesa loggana frá þeirri stöðu. Í fyrirlestrinum kemur Alex líka inn á nýjan fídus sem hleður viðeigandi hluta stöðuvélarinnar í minni ef hún kemst ekki öll fyrir í minninu - þetta þarf að gera handvirkt í dag.
Prevayler-mynstrið gerir HAppS kleyft að gera ýmsa sniðuga hluti, eins og keyra klasa af HAppS-þjónum og samræma stöðu á milli þeirra. Þannig er hægt að dreifa vinnslu á marga þjóna til þess að minnka álag á vélbúnað og koma í veg fyrir að vefir fari niður ef vélbúnaður deyr. Þetta þýðir líka að þegar uppfæra þarf hugbúnaðinn verða notendur ekki varir við neinn niðritíma. Annað sem mér fannst áhugavert við uppfærslur hugbúnaðarins og að koma þeim í rekstur er að þegar hugbúnaðurinn er þýddur verður til ein keyrsluskrá sem eingöngu þarf að afrita yfir á þá þjóna sem eiga að taka þátt í verkinu. Þjónarnir sjá alveg um að hlaða inn nýju útgáfunni.
Tegundakerfið (e. Type system) í Haskell er gríðarlega öflugt og mjög auðvelt og er það t.d. einsmóta XML. HAppS sér því um að flytja gögnin yfir í XML sjálfvirkt og því þarf eingöngu að umbreyta XML-inu, með hjálp XSL, yfir í annað birtingaform.
Mér finnst HAppS spennandi og ekki síður í því ljósi að HAppS virðist vera Haskell-leiðin í vefforritun. Hins vegar er ég hræddur um að þetta geti orðið erfið fæðing vegna lítillar skjölunar. Mér skilst að HAppS-liðið hangi á IRC-inu svo ég ætla að reyna að fá vísbendingar um hvernig er best að læra á græjuna.
Ferðin til S-Ameríku var frábær. Mikil upplifun þar. Ég freistast til þess að geyma bloggið um þá ferð í enn aðra færslu því það er talsverð vinna sem fer í að skrifa um 2ja mánaða ævintýri þar sem við ferðuðumst vítt og breitt um heila heimsálfu.
Í lok hvers árs hef ég ríka þörf til þess að gera árið upp. Það ætla ég hins vegar að geyma fyrir enn aðra færslu. Ég stend nú á enn einum tímamótunum í mínu lífi, bæði í einkalífinu sem og atvinnulífinu. Ég hef eytt síðustu dögum í að hitta mögulega atvinnuveitendur. Mig langar til þess að færa mig um set. Ég hef viðað að mér mikilli reynslu tengdum tölvum og ég finn að það nýtist mér vel en mig vantar meiri reynslu í viðskiptum/fjármálum. Mér finnst því líklegt að næsti vinnustaður verði í öðrum geira en ég hef hingað til starfað í.
Í nokkrar vikur hef ég velt því fyrir mér að byrja að blogga. Ástæðan fyrir þessum vangaveltum er sú að ég hef áhuga á því að taka virkari þátt í vefsamfélaginu. Ennfremur vil ég líta á bloggið sem faglega útrás á þeim sviðum sem ég hef áhuga á, þ.e. tækni (þá aðallega tölvutækni), fjármálum, ...
Það er hálfgerð hræsni að tala um að hafa áhuga á tölvutækni þegar þetta blogg er skrifað á eins frumstæðan hátt og mögulegt er. Planið er að nota þennan vettvang til þess að læra nýtt forritunarmál og byggja upp bloggkerfi og útvíkka það (wiki, o.s.frv.) svo fyrir vefsetur mitt en þangað til þá; textaskjal (blog.txt) og textaritill (Aquamacs). Forritunarmálin sem koma til greina eru eru flest fallamál, Python (ekki fallamál), JavaScript (í ætt við fallamál), Erlang, Objective Caml, LISP, og Haskell. Mig langar til þess að fara alveg nýja leið, stokka alveg upp hugsanaganginum svo ég held að lendingin verði að ég skrifi þetta í Haskell. Þessi póstur markar upphaf þessa ferðalags.
Bloggið er hins vegar ekki einu tímamótin hjá mér því ég er að skipta um vinnu, er að fara til Argentínu að hitta Guðrúnu (og ferðast með henni um Suður-Ameríku - efni í aðra færslu).
Þessi síða er heimili mitt á vefnum. Pælingin er að halda utan um allt efnið mitt á einum aðgengilegum stað.