發表文章

目前顯示的是 二月, 2012的文章

那一年,我們一起用Node.js開發3D使用者介面!

圖片
曾經想要用 Node.js 開發一些原生的應用程式或是 OpenGL 程式,但無論怎麼問,無所不答的 Google 大神都給我千篇一律的答案:『使用 HTML5 和 WebGL』。這答案其實不令人意外,因為截至目前為止,大多數學習使用 Node.js 的人都是 Web 開發者,其所提出的解決方案,理所當然都是與『瀏覽器』有關。想來有趣,Node.js 就是『與瀏覽器剛分手的 JavaScript Engine』,為何還要回頭與瀏覽器糾纏不清呢?於是,筆者開發並於 GitHub 釋出了一個 Node.js module - 『jsdx-toolkit』,讓 JavaScript 開發人員,可以輕易使用 Node.js 開發原生的桌面應用程式,更重要的是,不但可以寫炫麗的 3D UI,而且完全不需要靠『傻大個瀏覽器』。

如果想要載入圖片,並把物件 3D 旋轉,只需要這樣做:
var toolkit = require('jsdx-toolkit'); if (toolkit.init() != toolkit.INIT_SUCCESS) { console.log("Failed to initialize jsdx-toolkit."); process.exit(); } /* Create a new stage */ var stage = new toolkit.Stage(); stage.title = 'Rotate'; stage.resize(500, 500); stage.setColor(0, 0, 0, 255); stage.on(toolkit.EVENT_DESTROY, function() { toolkit.quit(); }); stage.show(); /* Load a image */ var texture1 = new toolkit.Texture; texture1.loadFile('fred.jpg'); texture1.setPosition(100, 100); texture1.rotate(toolkit.Y_AXIS, 30, 0, 0, 0); stage.add(texture1); toolkit.main();
當…

我的 Kinect 應用程式開發記錄

圖片
話說微軟(Microsoft) 這兩年為了 XBox 360 所推出的 Kinect 造成一股風潮,一夕之間,把 Wii 打的七零八落,取代了其體感遊戲機王者的地位,相比之下,Sony PS3 同一時期所推出的體感裝置,就顯得乏人問津 。
最近,筆者雖然忙錄,被很多麻煩的公事私事綁住,但每當睡前,仍抽空研究一些新技術。一方面是為了促使腦筋轉得更快,一方面是想加強許多 Idea 和 Business Model 的強度和完整性。於是,撿起丟在一旁生灰塵的 Kinect,嘗試著在上面開發一些應用。
由於『OpenKinect』眾高手的努力,所以驅動程式不是太大的問題,很久以前就已經能分別在 Linux、Windows 和 Mac 上驅動 Kinect。不過雖說如此,最困難的還是在於辨識演算法的相關設計,對於開發人員來說,你不過就是能得到攝影機的影像,就如同從 Webcam 上得到一樣,其他的圖學運算以及應用還是要自己動手。

當然,如果 Kinect 只是和一般 Webcam 一樣,那新聞媒體和許多人對他的誇讚,就太言過其實。其最大的不同在於,Kinect 有深度感測,這意味著我們可以得到實際的空間資訊,以工程的方式,大大減少辨識演算法的難度,並提升了辨識系統的精準度。
這次的嘗試,焦點放在辨識演算法之上,便開始思索各種方案。過程中,試了數種別人已經開發好的函式庫,都不甚滿意。倒不是效果不好,而是系統需求太大,開發語言大多採用  Java ,所以需要安裝一卡車的模組程式以及 JVM。有些更是對 Linux 的開發者不夠友善,或開發支援不夠完整。無論哪一種現有方案,都不足以讓筆者可以安心建構在上面然後開發下去,因為產品化和易移植性,對筆者來說是相當重要的考量,不是只要學術驗證而已。所以最後決定,自己手動設計演算法,採用 C/C++。
經過這幾天睡前的努力,可以看到開發過程中的截圖,演算法初步已經能辨識手掌,並抓取指尖位置,精準度已達可用的程度。接著,只要多做些簡單的開發,撰寫 X11 輸入裝置驅動程式,就能實際以多點操控的型式,操作螢幕上的所有應用程式。

此外,這裡有一些心得,Kinect 深度感測的數值範圍是 0 ~ 2047,至於得到的深度數值如何換算成實體距離,這邊有個公式可以換算成公尺(Meter)的型式:
Real Distance = 1.0 / (raw_depth *…

用 NodeJS 打造守護神常註程式

寫系統程式很常會需要碰到實作常駐程式,這意味著你必需要讓程式在背景執行,然後提供服務或是等待事件觸發,如『親手打造一個背景執行的Daemon程式』所提到,若用 C 語言,做法大致如此:

void main() { pid_t pid; pid = fork(); if (pid>0) { exit(0); } }
而在 node.js 上可以使用『daemon』模組,輕易打造常註程式。
$ npm install daemon
使用方法如下:
var daemon = require('daemon'); /* Become a daemon */ daemon.start(); /* Loop to do something here in background */
執行後,程式應該會立即返回並結束,但是若用 ps 等系統工具程式去看目前正在執行的 Process,會發現我們的程式已經運行在背景了。

JuDaemon 完全取代 GNOME 的最後一根稻草

我們不得不承認,GNOME 為了整合桌面環境,曾經開發了很多好用的整合性的元件,像是桌面背景控制、圖型化元件樣式、螢幕設定監控和更多桌面功能的設定程式。對於我們這些不愛 新版 GNOME 的使用者來說,常常是改用其他桌面環境(如:LXDE、E17 或單純用 Awesome window manager),再配上 GNOME 的這些整合性元件。

不久前,雖然 GNOME 進入了 3.0 時代,但這些整合性元件依然存在著,並不隨著版本上升而有所太大改變,這對我們這些『不肯升級的使用者』是很好的消息,沒有太大的影響。不過,在最近幾個月,GNOME 已經將這些元件一一消滅,整併進去其他的專屬程式當中。在 Debian 上,gnome-control-center 更是已經毀損(如果你沒有裝新版的 GNOME 3.0),更進一步,許多重要的系統常駐程式一一失效(如:gnome-settings-daemon 和 gnome-power-manager 等),不再如同過去可以輕易單獨使用。

GNOME 所帶來的毀滅,已經嚴重影響到筆者現有的使用,所以打算再次繼續原本停滯一段時間的 Juice Desktop Environment (詳情可參考『新鮮果汁吧!果汁桌面環境(Juice Desktop Environment)!』),過去曾開發過『JuShelf』,就屬於這計劃的元件之一。

大概評估了工作,主要就是系統監控程式的實現,也就是取代舊有 gnome-settings-daemon 的功能。對筆者個人而言,目前只有幾種簡單需求:

電源管理:螢幕休眠、電腦蓋上後自動休眠、AC 電源切換通知和低電壓通知。螢幕設定:插上外接螢幕後自動偵測,拔除時也自動恢復成單一螢幕(現在是一片黑)。OSD支援:調整螢幕亮度、音量時,可以跳出畫面顯示目前亮度和音亮。
日後當然還需要有圖型化程式,可以微調這些細部設定,不過不是初期主要的工作(相信會選擇不用 GNOME 的人,應該都有能力自己改設定檔)。
筆者成立了一個新的 Project -『JuDaemon』,就是為了解決這樣的需求,目前只完成了螢幕自動休眠的部份,尚有其他工作待繼續。如果您有興趣,可以提交 patch 或是加入這個專案一同開發。:-)
後記
考慮到筆者近來比較常用 github ,而且 github 的開發者相對踴躍交流,過一段…

那一年,自由軟體變成統獨論戰的題材

對於我們這種『宅宅水電工』,唯一的樂趣就是經營技術,閒暇招三五同好,玩玩新東西。但怎麼也沒想到,我們這種人做出來的東西,卻變成有心人『統獨論』的撰文題材,令人又好氣又好笑。原始文章出自這篇『台灣人缺乏自信之實例 』,是筆者在閒逛 Google 時搜尋到的,因為有提到自己的名字,就特別點進去看了一下。被說成缺乏自信心,甚至要被除去,百般無奈。

還記得 LXDE 剛開始會為人所知,是因為 PCMAN 於一些台灣社群活動中,首度公開設計理念,當時雖然許多人叫好,但真正參與開發或專案的確寥寥無幾,一段時間折騰下來,包括我在內的開發者和參與貢獻者,不過五六人,甚至 PCMAN 寫了大量的程式,一度荒廢了自己的學業和醫生本業。

說起來心酸,為了得到台灣社群的認同,我們無不熱衷於在台灣各個大小場合,推廣和號招開發者以及有興趣的人加入。當然, 我們不是外國人,都是使用『中文』與其他人說明和討論技術問題,也極力確保軟體都有中文的介面。甚至成天掛在 IRC(相當古老的網路聊天系統,目前仍被全世界的駭客和開放源始碼廣泛使用) 上,與網友以『中文』討論諸多相關問題。當時許多文件和簡報,同時存在著中文和英文版,甚至很多只有中文版本。

LXDE 的成員身體力行在台灣走透透,卻沒想到也能招來不少外國人。在推廣過程中,開始接觸到許多國外來的開發者和自由軟體愛好者,也開始在各國都有人自動自發要幫忙翻譯成各種語言,然後台灣以外的許多愛好者也開始大量使用 LXDE 並回報問題,甚至提交他們修改過後的程式 patch,參與貢獻。我只能說一開始, LXDE 只有一堆一般人不易讀懂的程式碼,後來的許多非中文的文件和說明, 很多是出自於這些外國貢獻者之手。

註:差點忘了提,LXDE 的網域名稱,還是一位印度人所贊助的。

『自由軟體和開放源始碼』會為我們這些宅宅水電工所喜愛,就是能與所有的同好者,一同完成這些程式和專案。但是,這些自由軟體本來就只是花費我們的課餘時間和下班閒暇時間,不可能什麼東西都能親力親為,我們唯一能做的,就是將自己的初衷做好 。所以,LXDE 後來在國外會有一些知名度,也不是一開始所能預期的,更別提到是不是以台灣為榮,那都是不重要的後話。

若真要說到活在台灣的心態,我只能說:『我們在台灣長大,只是將在台灣這一二十載所學的一一展現出來,如此單純而已。』。我們挺胸開發自己的程式,一步步『意外』走…

有技術的創業者、SOHO族和個人接案者趕緊來吧!

這是創業者的心聲,我們永遠為了為數不多的錢,拼老命和客戶周旋。在客戶面前包到好包到腳,扛的責任何其多,回來後又當業務又當 PM 還要當 R&D,最後還得當會計,數不盡的心酸誰知道。沒辦法,對我們來說,現金流(CashFlow)比什麼都還重要,能不能挺過這個月或下個月,維持周轉才是首要任務,為此,任何苦我們也得吃下。

筆者做了幾年的 Outsourcing,雖然不是當初創業的核心目標,但為了養家活口,接案卻成了主要業務。不過,筆者確實也因接案而活了下來並壯大團隊,能夠有機會持續朝理想發展。接案的過程中,風風雨雨自然不在話下,但慶幸受到前輩和朋友間的提攜,近來也總算是開始有個根基,剛好穩住腳。

接案就是這樣,有一頓沒一頓,如果要穩定收入,案子的價與量就必需相應提高,這是所有以接案當食糧的創業者,所都要經歷的過程。但是,往往在提升價和量後,案子開始會吃掉團隊的全部時間,漸漸失去當初創業的核心目標。然後,進入了『招人力』後『招案子』再『招更多人力』後『招更多案子』的惡性輪迴中,最終你會想:『辛苦到快暴斃,工時責任換算下來,賺得比去上班來得少,那我何必創業?』。如果你有同感,不用灰心,因為現在有無數的創業團隊和創業者, 也都正面對著同樣問題,甚至面臨崩潰。

有鑑於此,筆者尋思,何不與大家分享自己的經營成果,讓大家各自都能得到更多時間經營自己的核心目標?創業者、SOHO族和個人接案者所需要的源源不絕的食糧,不必各自重新發展重新耕耘,只需要從筆者這接手過去即可。由於舊有團隊原本已經有業務和PM的佈署,大家也可專注於技術性的工作,並提供如自來水般的技術供應即可。

對筆者來說,自己的核心技術團隊得以鬆口氣, 能慢慢以階段性放下養活自己的短期目標,有更多時間朝自己原本創業的核心目標前進。另一方面,也能給予其他創業者、SOHO族和個人接案者穩定的收入支持,不必重蹈覆徹筆者同樣的道路。如此雙贏的局面,樂見其成。

所以,如果你們是有技術的創業者或創業團隊,SOHO族或個人接案者,趕緊來報到吧!

後記

無論你是專精或有經驗於哪一領域(Web、Linux、Android System(Integration/Porting)、Android App、iOS App 或 Embedded System... etc),都歡迎來信,最少先交個朋友也是不錯的。:-)

用 XRandR Extension 監控螢幕設定變化

最近一直感覺到系統有時莫名緩慢,CPU 負載也相當高,初期沒去注意,也一味的相信應該都是瀏覽器開太多網頁和 Flash 檔案所造成的,但種種情況令人不解,總覺得不完全是瀏覽器所造成的。將所有瀏覽器關閉後追蹤發現,自己之前寫的『JuShelf』(Dock 程式)竟吃掉近 50% 的 CPU 資源。原兇是之前寫的一段程式,用來偵測目前螢幕設定是否有改變,並依據螢幕設定而調整顯示位置,以讓 Dock 永遠顯示在螢幕的中央。

原本的做法相當笨,利用 g_idle_add_full() 讓程式空閒時就去偵測螢幕設定,但由於 Dock 通常是晾在一旁沒有工作的,所以程式經常有空閒時間,這讓程式以每秒百計的次數不停檢查。這還不打緊,由於每次檢查都要與 X Server 做一次至數次溝通,付出的代價更為高昂。

抓到臭蟲以後,便開始著手改進,使用了 XRandR Extension 來取代原有的解決方案。過去筆者曾撰文『寫支 C 程式用 XRandr Extension 設定你的螢幕解析度』說明 XRandR 的使用方式,不過當時只著重於取得 X Server 的顯示設定,這次將利用 XRandR Extension 以等待 RRScreenChangeNotify event 來得知螢幕設定何時改變。

由於完整程式太長,這邊只摘錄重點片斷,主要是檢查 XRandR 版本和註冊事件:
int rr_major_version, rr_minor_version; int rr_minor_version, xrandr_error_base; /* Initializing X Stuffs... */ /* XRandr extension */ XRRQueryVersion(disp, &rr_major_version, &rr_minor_version); if (rr_major_version < 1 || (rr_major_version == 1 && rr_minor_version < 2)) { printf("RANDR extension is too old (must be at least 1.2)\n"); return 1; } /* Allow XRandR Extens…

NodeJS 應用佈建快手:利用 package.json 處理麻煩的模組相依性

NodeJS 日益強大,相關開發資源也越來越多,許多功能已經不再需要自己寫,通通都可以直接利用官方的 NPM(Node Package Manager)工具,從網路上把別人已經開發好的模組抓回來用。這樣的模組交換平台加快了開發速度,讓開發者可以全心全意專注於當前應用的開發工作。但是也因為如此,讓我們的 Project 總是相依於一大堆的第三方模組,而每當要將我們的程式佈建於伺服器時,就必需手動先將所有的模組先安裝好,甚至是用最笨的方法邊試邊裝遺漏的模組。

事實上,我們可以在程式目錄中,建立 package.json 檔,直接管理 Project 的相依性以及所使用到的模組套件:
{ "name": "my-website", "version": "0.0.1", "private": true, "dependencies": { "express": "2.4.7", "jade": ">= 0.0.1", "oauth": ">= 0.9.5" } }
一旦目錄中存在 package.json,下次要移到新的環境裝起來時,可以直接利用 NPM 把所有的相依模組一次裝好,省下很多功夫:
$ npm install

使用 NodeJS + Express 從 GET/POST Request 取值

過去無論哪一種網站應用程式的開發語言,初學者教學中第一次會提到的起手式,八九不離十就是 GET/POST Request 的取值。但是,在 Node.js + Express 的世界中,彷彿人人是高手,天生就會使用,從不曾看到有人撰文說明。

這應該算是開發 Web Service 的入門,在 Client 與 Server 的互動中,瀏覽器發出 GET/POST Request 時會傳值給 Server-side,常見應用就是網頁上以 POST method 送出的表單內容,或是網址列上的 Query Strings (ex: page?page=3&id=5)。然後,我們的網站應用程式透過解析這些參數,得到使用者上傳的資訊。

取得 GET Request 的 Query Strings:
GET /test?name=fred&tel=0926xxx572 app.get('/test', function(req, res) {     console.log(req.query.name);     console.log(req.query.tel); });
如果是透過表單且是用 POST method:
<form action='/test' method='post'> <input type='text' name='name' value='fred'> <input type='text' name='tel' value='0926xxx572'> <input type='submit' value='Submit'> </form> app.post('/test', function(req, res) {     console.log(req.body.name);     console.log(req.body.tel); });
當然也可以 Query Strings 和 POST method 的表單同時使用:
<form action='/test?id…