Language

Thursday, October 1, 2020

社群媒體關機一個月的實驗

自從 2019 年五月看了《深度工作力》這本書之後,知道了以前我工作高效率的原因,也知道了我現在的效率跟以前有一段不小的差距,去年開始針對專注力的提升做了一些改變,今年八月又重看了這本書,還順便加碼了《深度專注力》與《最有生產力的一年》,其實講專注力或生產力的書都有幾個重點,就是要增加專注力,減少干擾,增加靈光乍現的機會。前兩者是大腦的「專注模式(focus mode)」,最後一個是大腦的「放鬆模式(diffuse mode)」。這是我在 "Learning How to Learn" 的線上課程裡面學到的,專注模式是得到思考的材料,放鬆模式則會把這些材料聯結起來。事實上我從研究所就開始這麼做,我喜歡專注研讀一些材料之後去散步,通常有很大的機會,在散步的時候就會出現靈感。但我其實發現,使用 social media 愈多,我的專注力就愈低,而且「放鬆模式」就愈少,因為滑手機滑多了,在我們等待任何事情的時候,都很容易拿起手機,然而,大腦覺得無聊的時候,正是進入「放鬆模式」的黃金時刻,也就是說滑手機其實剝奪了靈光乍現的機會。這個卻是我在最近才猛然驚覺的,而且也在這幾本書裡面證實我的想法。也因此,我就依照《深度工作力》一書的建議,來把我平常最常在休息時間滑的社群媒體關機一個月。

原先手機或網路幾乎都是不離身的,我想現代人大部分都是拿手機當鬧鐘,一起床就拿起來看時間,看看天氣,然後就順便滑一下臉書、推特或是 Instagram 等等社群媒體,接著上廁所可能也帶上手機順便看看新聞,或是繼續滑臉書,畢竟臉書真的很多內容要滑的啊(笑)。然後準備上班前用 Google 導航看一下路況,看看今天天氣預報,然後出門,出門依照每個人選擇的交通工具不同,搭大眾運輸的,全程繼續滑手機,騎機車或開車的,等個紅燈就會拿起來滑,到了公司搭電梯,很多人也是在等電梯的時候就拿出手機來滑,進了電梯繼續滑,有些人甚至走到座位前還繼續滑。工作的時候,雖然手機不方便拿起來滑,但現代辦公室也有公司用的 social media,還有 email,《最有生產力的一年》書中就有提到,根據 RescueTime 的調查,一名知識工作者每天平均打開電子郵箱五十次,並使用即時訊息七十七次。工作之餘的休息空檔,大腦會很想要補充多巴胺,就更想要趕快拿起手機滑了。吃飯時間,不管是獨自用餐或是話題開始冷掉的時候,都會拿起手機滑。等到回家休息,就是滑手機的重點時刻了,畢竟工作累了一天,大家也都是下班之後開始猛力 post 文章,有好多要滑的啊。到了晚上就寢時間,躺在床上等睡意來襲的時候,也會順便拿起手機滑,反正都要等嘛。於是一天之中,第一眼見到的是手機,最後一眼見到的也是手機,這就是現代人的網路生活。

在這一個月裡面,我盡我最大的努力減少網路的使用。我把我最常用的 social media 在我手機移除,只保留了無法避免或是很少在用的(我沒有要真的完全與世隔絕)。早上的鬧鐘也改成實體的鬧鐘,手機會放在房間充電以防有緊急事件,但不是我唾手可得的距離。上廁所也不帶手機(我相信很多人都會帶手機去滑啦,但大家可能都會很不好意思承認),我一天檢查必要的 social media 一到兩次,檢查 email 一天大約三次,儘量把網路都安排在同個時段處理(《深度工作力》中所謂的 shallow task 時段)。為了減少在辦公室被打擾,我也會戴上抗噪耳機。等電梯等紅燈這種無聊的時刻,也不拿起手機來滑。我的原則就是:
- 不打開網路應用的通知
- 需要用網路的時候,就把他們集中在同個時段處理
- 大腦覺得無聊的時候,不拿起手機來排解這個無聊
- 想到要在網路上查什麼資料,不要立刻去查,先記下來,至少等五分鐘以後才去查(避免大腦的獎勵迴路)
- 大腦有任何想法出現都先記在筆記本上,以便清空短期記憶
- 想到要在網路上分享什麼事情的時候,等個半個小時以上再說,通常這個念頭都會消失(也是避免大腦的獎勵迴路)

這些改變不是一次到位,是逐漸加入的,以防止猛烈的戒斷症候群(笑)。我也依照《深度工作力》裡面的建議,一直不斷的安排一天接下來的行程,思考什麼時候要排深度工作,什麼時候要排淺薄工作,如果行程有變,那就繼續安排接下來的行程,保持彈性,也不去強迫自己一定要非常依照原先的行程,但原則就是一定要事先安排。然後深度工作我一定會跑番茄鐘,幫助自己快速進入專注模式,稍有分心,也會看一下時間,就繼續拉回原先專注的事情。有任何想法或要計畫什麼事情,也都是在筆記本上紀錄,我一直維持紙本萬用手冊的習慣,當然還有工作日誌也是紙本的。

那麼我有什麼改變呢?大約一週之後,我的專注程度就大幅增加了,而我在大約十五天之後很驚喜的發現,想要放鬆娛樂自己的時候,第一個念頭不是開 Netflix 也不是滑手機,而是拿起書來讀。比方說我吃完晚餐之後,坐到沙發休息的時候,就會順手拿起書來讀。有時候看 Netflix 也不再像以前一樣一直連續看下去,而是看個一兩集就停止了。大約三週之後,我的靈感回來了,我在散步的時候、淋浴的時候,靈感是源源不絕的出現,我都會隨身帶個小筆記本記錄下來。這段時間,我也發現自己會在路上或電梯中,跟陌生人交談。一個月後的今天,我很滿意自己的改變,可以說我的自信也提高了,這時候就讓我引述一下這段時間一直出現在我心中的一段聖經:「箴言 16:32 不輕易發怒的勝過勇士,制伏己心的強如取城。」

一個月關機的時間,其實很快就過去了,接下來 social media 重開機的漫漫長路,才更是對抗網路這個專注力殺手的長期抗戰。不過,把握上述幾個原則,就能把網路對於專注力的殺傷力降到最低。而且 social media 關機一個月的實驗也讓我了解到,這些 social media 真的沒有那麼重要,但我不是說人際互動不重要,事實上,關機的時刻,讓我更體會到人際互動的重要性,但 social media 的互動無法滿足人際互動需求的深度,只有當面或是電話才能夠滿足這種深度,而且也更節省時間,換句話說,更有生產力。

Monday, May 30, 2016

以頻率計數器來看 Undersampling

以頻率計數器來看 Undersampling

以頻率計數器來看 Undersampling

由於 blogspot 會被某些公司擋,我已經著手將這裡的文章慢慢的移到 GitHub Pages 上面,這篇文章可以在 這裡 看到

1 頻率計數器問題

想像一下你現在有一套嵌入式系統軟硬體,你只能偵測外部輸入是高或低電位(也就是 GPIO),你要測量外部的方波的頻率,你要怎麼達成呢?我想你能夠達成的就是,固定時間,比方說每隔 1 µs 「偵測」一次訊號位準是高或低,然後標定由低變高以及由高變低的地方,並且計算這個「由低變高」的週期,再轉換成頻率吧?你還能想到更簡單精準的方式嗎?歡迎來挑戰。

2 如何計算頻率?

Figure 1: 頻率計數

由圖 1 可以計算頻率,圖中黑色的方波是你要計算頻率的波形,而橘色的方波代表了你讀取外部 GPIO 值的時間點,綠色就是讀取到的值。\(T_0\) 是要計算的方波週期,從圖上的格子點來計算(假設一格是 1 µs),是 16 µs,\(T_s\) 是讀取 GPIO 的週期,是 4 µs,計算出來的頻率週期是 $Tc$,是 16 µs,就是訊號「看起來變回一週期同樣位置的」週期(為什麼強調這一點?因為要真正計算頻率,也是有點技巧的,這技巧叫做 frequency estimation,有機會再講,你的大腦比數學公式強多了,呵呵)

這裡 \(T_0 = T_c = 16 \mu s\) , 咦?可以精確的計算出來方波頻率呢。

我們改用頻率來看這些數值 \(F_0 = F_c = \frac{1}{T_0} = \frac{1}{T_c} = 62500 Hz = 62.5 kHz, F_s = \frac{1}{T_s} = 250000 Hz = 250 kHz\)

3 這跟取樣有什麼關係?

啊,這就是取樣啊,取樣就是這麼單純的一件事。「用同樣的頻率去觀察這個世界」,就是取樣的基本意義。上一篇文章「淺談取樣定理」就是在闡述這件事,所以,用固定的週期,去觀察 GPIO 的值,你說他跟取樣定理沒關係嗎?錯啦,他就是取樣定理的一個應用,所以取樣定理的 Nyquist rate 一樣會應用在這個過程中。所以 \(F_s \ge 2 * F_c\) 所以可以成功的取樣完整的訊號,等等,好像哪裡不對吧?先別說這個了,我們來看萬一你的計數頻率低於要偵測的頻率怎麼辦。

4 如果你的計數頻率低於要偵測的頻率呢?

如果你要計數的頻率低於要偵測的頻率,會發生什麼事呢?按照前面的流程,我們就畫一下波形來看看。

ZeroCrossingUnderSampling.jpeg

Figure 2: 頻率計數 Undersampling

2 就是 undersampling 的情況,一樣黑色方波是要計算頻率的波形,而橘色方波代表讀取外部 GPIO 值的時間點,綠色就是讀到的值。

\(T_0 = 4 \mu s, T_s = 6 \mu s, T_c = 12 \mu s\)

換算成頻率

\(F_0 = 250 kHz, F_s = 166.667 kHz, F_c = 83.333 kHz\)

哇,你說這怪怪的吧,我原本的頻率是 250 kHz,取樣後變成 83.333 kHz,你說,啊對,因為低於 Nyquist rate,所以無法取樣到正確的頻率,所以把這個資訊丟棄吧!不,這個資訊還是有用的,這個是低於 Nyquist rate 的時候,會看到的現象。在這裡,因為你在方波的正緣與負緣都取樣,所以其實真正的取樣率 $Fs = 333.333 kHz$,這就是上一節怪怪的地方(有看出來嗎?)我為什麼這麼做呢?因為在某些數位的計數器就是這麼做的,正緣與負緣都偵測一次,如果值改變了,就累計一次,沒改變就不累計。這種情況下的取樣頻率你要乘以二。

好啦,重點來了,\(F_s - F_0 = 333.333 - 250 = 83.333 kHz\) ,這巧合吧,你說。再次有圖有真相,我們來畫圖。

FrequencyAmbiguity.jpeg

Figure 3: Frequency Ambiguity

3 是我們常見的取樣圖形化分析方式1, \(F_0\) 是你觀察的訊號,他的頻率高於 \(\frac{F_s}{2}\) 。取樣後我們能看到的頻率範圍只有橘色所框住的 \([-\frac{F_s}{2}, \frac{F_s}{2}]\) 而已,所以高於 \(\frac{F_s}{2}\) 的我們就畫一條水平線,看他與橘色範圍的三角形交叉的點在哪裡,計算其頻率,那就是你取樣後的頻率。在我們這個例子中可以看到 $Fc < 0$,計算出來是 $Fc = F0 - Fs = 250 - 333.333 = -83.333 kHz$,先不看正負號,週期跟圖 2 算出來是一樣的吧?負號只是影響相位而已,不影響頻率。

5 結語

筆者發現每次寫部落格文章,最頭痛的就是畫出那精美的圖形,本來用 Python matplotlib 已經夠簡單了,不過還是要花點時間,所以部落格文章發表都拖很久,從這篇文章開始,筆者改用手繪!讓大家看到我醜醜的手寫字真是有點不好意思,不過這樣子可以發文章發得比較快一些。本篇就是承襲上一篇文章的取樣定理,在嵌入式系統或是數位設計常常會遇到的計數器問題上舉個例子,讓大家看看取樣定理是怎麼應用的,其實很常見啊,不是只有你在接收 ADC 傳進來的資料才會遇到喔!希望大家喜歡今天的文章!

Footnotes:

1

參見 Richard G. Lyons, "Understanding Digital Signal Processing," 3ed, Prentice-Hall, 2011.

Author: Albert Huang

Created: 2016-05-30 Mon 22:02

Validate

Wednesday, May 25, 2016

淺談取樣定理

淺談取樣定理

淺談取樣定理

由於 blogspot 會被某些公司擋,我已經著手將這裡的文章慢慢的移到 GitHub Pages 上面,這篇文章可以在 這裡 看到

1 來個取樣的思想實驗

想像你的房子剛好有個窗子,能看到窗外有個摩天輪,這個摩天輪有 360 個座位,以逆時針方向依序編號,但不巧,你的視角只能看到一台車。如果你固定兩個小時的整點觀察一次該摩天輪,發現每次都是編號第 180 的車,請問該摩天輪的轉速是多少?還是該摩天輪根本就沒轉呢?

那麼如果你增加觀察的頻率,固定每個小時的整點都觀察一次該摩天輪,發現這次不一樣了,每個小時觀察到的車輛編號是 0, 180, 0, 180 交替出現,那這代表什麼呢?恭喜你,至少確定排除摩天輪不轉的可能性。那麼該摩天輪的轉速到底是多少呢?每兩個小時觀察到他會轉一整圈,那麼是每小時半圈嗎?答案是:不一定。

這次我們換個角度來想,已知摩天輪每兩個小時轉一整圈,那麼你最少要用多快的觀察頻率,才能知道摩天輪的正確轉速?

如果你用跟摩天輪轉速相同的頻率,也就是每兩個小時觀察一次,那你會跟第一段的觀察結果一樣,看到每次都一樣的車輛編號,導致你根本就不知道他到底是有轉還是沒轉。那如果你用每個小時觀察一次,也就是兩倍於摩天輪轉速的頻率來觀察,那你會看到跟第二段一樣的結果,也就是每個小時剛好是相反的位置被觀察到,換算成轉速是每小時 0.5 圈,那如果變成四倍,也就是每 30 分鐘就觀察一次呢?摩天輪每兩個小時轉一整圈,那每 30 分鐘就是轉 1/4 圈了,那你會看到 0, 90, 180, 270, 0, 90, 180, 270,換算也是每小時 0.5 圈,看來你已經可以正確觀察到摩天輪轉速了,更高的觀察頻率應該也可以觀察到正確的轉速,你心裡想。可是最少要多少頻率才能觀察到正確轉速呢?

這次我們每一個半小時觀察一次,上一段我們知道每 30 分鐘,摩天輪會轉 1/4 圈,所以每 90 分鐘觀察,摩天輪會轉 3/4 圈的角度,也就是 360 * 3/4 = 270 個車輛,從 0 開始的話,會依序觀察到 0, 270, 180, 90, 0, 270, 180, 90, 0, …….,如果這次是你第一次觀察到的結果,你可能會很興奮的下結論說這個摩天輪每 4*90=360 分鐘轉一圈,而且方向是與編號方向相反方向的。可是我們已經知道摩天輪每兩個小時轉一圈啊,這個結果跟已知不合啊。所以低於轉速兩倍的觀察頻率看來也是不行,有興趣的讀者可以嘗試其他低於兩倍的觀察頻率,看看結果是如何?

那現在同樣的摩天輪,但你搬家了,變成只能看到摩天輪的地面,剛好在編號 0 的車輛上,有一個雷射光束,永遠指著地面,而你能夠觀察到地面的雷射光束位置。

高中數學告訴我們,雷射光束的位置與編號 0 的車子被轉的角度有一個關係,那個關係叫做 \(cos \theta\), 這裡假設摩天輪的半徑是 1,那在地面雷射光束的位置就是 \(cos \theta\) 了,所以地面位置用 +1 到 -1 來表示。

回到摩天輪觀察頻率,如果我們用每兩個小時觀察一次的頻率,我們會看到雷射光束一直都指在同一個地方,為了方便描述,我們就說他一直都是在 +1.0 的位置上。畫成圖就會像圖 1 所示。

SamplingRate_1.png

Figure 1: 取樣頻率等於訊號頻率

那如果我們每個小時觀察一次,雷射光束指的位置又會有什麼變化呢?如果我們在相同位置觀察到 0, 180, 0, 180, ……, 那麼第 0 輛車的位置就會在 +1.0, -1.0, +1.0, -1.0, …… 變化了,畫成圖的話就變成:

SamplingRate_2.png

Figure 2: 取樣頻率兩倍於訊號頻率

在訊號處理的領域上,我們習慣將取樣到的點與 X 軸連接起來,來表示它是取樣資料,就像下圖這樣:

SamplingRate_2_a.png

Figure 3: 週期為 2 hr,頻率 \(F = \frac{1}{2}\) cycles per hour 的正弦波,以 \(F_s = 1\) cycles per hour 來取樣(\(F_s = 2*F\))

在圖 3 我們引入了週期以及頻率的觀念,這裡我們用的頻率單位是 cycles per hour,也就是每小時的轉速,轉換成每秒的轉速就變成 \(\frac{1}{3600}\) cycles per second,也就是 \(\frac{1}{3600}\) Hz(Hz 這個單位一直到 1960 年代為了紀念赫茲(Heinrich Hertz) 以後才被廣泛使用,在此之前都是以更直接的 cycles per second 這種一目了然的單位來表示),正弦波的一個週期,就是上述的摩天輪轉一圈回到原點,所以會用 cycles 喔!

那麼如果我們回頭看剛剛那個以 1.5 小時取樣率的結果,畫成圖來看呢?注意算一下圖上的訊號週期就是 6 小時(X 軸的單位就是小時),與我們剛剛計算的結果是一樣的,也就是 360 分鐘轉一圈。

SamplingRate_1.5.png

Figure 4: Fs = 1.3333 * F

那我們如果取樣頻率更高一些呢?比方說四倍?我們來看一下結果:

SamplingRate_4.png

Figure 5: Fs = 4 * F

5 看起來就像是圖 3 的細緻版,只要每四點取一點,就會變成取樣率只有兩倍的那張圖。而這個「每 N 點取一點」也就是訊號處理 decimation 的基本觀念(不過當然不只有這樣,還需要做一些濾波的動作),但這就是基本的取樣率轉換的概念,在這篇文章裡面我們不詳談,有機會筆者再詳細說明。

SamplingRate_2_b.png

Figure 6: 週期為 \(\frac{2}{3}\) hr 的正弦波,以 \(F_s = 1\) cycles per hr 取樣

回到本文的第二段,為什麼看起來一樣的圖形,不一定代表一樣高的頻率訊號;圖 6 看起來跟圖 3 是完全一樣的圖形,但其實他的原始訊號頻率高三倍,不信我們將取樣率再高一些,變成 3 倍看看,如圖 7 所示。

SamplingRate_2_c.png

Figure 7: 週期為 \(\frac{2}{3}\) hr 的正弦波,以 \(F_s = 3\) cycles per hr 取樣

這是因為在數位訊號的領域上,不能表示真實的頻率,所有的頻率只剩下 [0, 1] 或是 \([0, 2\pi]\) ,前者稱為 normalized frequency, 單位是 cycles/sample,後者的單位則是 radian/sample,要轉換成真實的頻率,就需要把取樣率考量進來,變成 \([0, \frac{F_s}{2}]\) Hz,所以在數位訊號處理中,取樣率是個非常重要的參數喔!

而圖 6 取樣率是 1 cycles per hour,被取樣的訊號是 1.5 cycles per hour,最後得到的數位訊號是 1 cycles per hour,這個現象稱之為 alias,是我們一般要避免的,但有時候也會刻意採用這種取樣方式,筆者在下一篇文章會講相關的議題。

2 Nyquist Rate

我們常常會聽到某訊號的 Nyquist rate 是多少?其實就是上一段直觀結論的數學版,一個 F 頻率的訊號,要用 \(F_s = 2*F\) 的取樣頻率來取樣,才能夠完整表示這個訊號,這個 \(F_s = 2*F\) 就是 Nyquist rate,有時候這又稱為取樣定理,或是 Shannon Sampling Theorem. 這裡的 Shannon 就是那個 Claude E. Shannon 啦。這起源於 19xx 年代,美國的電話公司開始數位化語音訊號,當時用的是 64kbps PCM(Pulse-Coded Modulation, 是一種用脈衝振幅來代表訊號大小的一個數位傳輸方式),為了節省頻寬,電話公司當然是要研究怎麼樣才能用最少的取樣頻率來傳遞語音訊號,Nyquist 採用的方式比較像是工程師直接量測與觀察得到的結論,而 Claude E. Shannon 則是後期利用取樣與 FFT 的關係,用數學式來描述,所以同樣內涵的取樣定理,有人稱之為 Nyquist Sampling Theorem,也有人稱之為 Shannon Sampling Theorem, 或是 Nyquist-Shannon Sampling Theorem,至於量測得到的結論,與數學式表示誰比較重要,我認為是兩者都重要,因為還沒有什麼理論是不需要實際驗證的,在理論能建構之前,大部分時候,也無法憑空想像出來,因為實驗就是了解上帝所創造的這個世界的方式。歸納永遠比演繹來得早,但歸納與演繹缺一不可;歸納能讓你了解系統現象,演繹則能讓你在腦海中從事思想實驗並大幅推廣。

3 取樣率與取樣頻寬

既然單一頻率的正弦波可以用他的 Nyquist Rate 來正確取樣,那麼所有頻率低於這個頻率的正弦波也可以用同樣的取樣率來取樣,所以我們一般會說 \(F_s \ge 2B\), \(F_s\) 是取樣率, B 是所需的訊號頻寬。

4 那我到底要多少取樣率呢?

是的,了解最低需要兩倍的取樣率之後,在訊號處理領域裡面,永遠都會再繼續問這個問題:到底要多少取樣率才夠呢?取樣率高有什麼好處與壞處?在市面上強調高取樣率的,最常見的就是音效卡,明明已經說了音樂到 20kHz 的頻寬就足夠,而 CD 取樣率也只有到 44.1kHz 而已,但你還是可以看到 96kHz 甚至 192kHz 取樣率的音效卡,那取樣率比 Nyquist rate 高這麼多有什麼用處呢?這有很多實作上的考量,先不談這個,你聽過錄製音樂的 CD 嗎?

5 說個 CD 取樣率 44.1 kHz 的小故事

一般會說人耳能夠聽到的範圍是 20 kHz,各位讀者現在也知道了只要兩倍的取樣率就足夠了,那為什麼 CD 的取樣率是 44.1 kHz 呢?那為什麼 DAT(錄音室比較常見的數位錄音帶)是 48 kHz 呢?根據維基百科,這要講到 1979 年 Sony 出了一台 PCM-1600 的裝置,可以在一般的卡帶上錄數位聲音,上面的取樣率就是 44100 Hz,因此 1980 年制定 CD 的標準的時候,就採用這個取樣率。那麼為什麼是 44100 Hz 而不是 40 kHz 呢?首先,要送進 ADC(Analog-to-Digigal Converter) 之前,要先經過一個低通濾波器,而真實世界的濾波器不會「嘎然而止」,而是會「漸漸停止」,這個「漸漸」就是 transition band,transition band 寬一點,濾波器比較容易設計,所以預留了 2.05kHz 的 transition band,那為什麼不是更多呢?當年電視是 PAL 與 NTSC 的時代,都是類比的,現在也幾乎看不到了,所以以當時的技術來說,44100 Hz 可以同時與 PAL 與 NTSC 相容,因為:

NTSC:

  • 245 * 60 * 3 = 44100
  • 245 active lines/field * 60 field/second * 3 samples/line = 44100 samples/second
  • 每個 field 245 條垂直掃描線(整張畫面的主動掃描線是 490 條,但全部有 525 條,但 NTSC 時代每次只更新半張畫面)
  • 每秒 60 field(所以每秒是 30 張)
  • 主要使用在北美
  • 北美交流電是 110V, 60Hz

PAL:

  • 294 * 50 * 3 = 44100
  • 294 active lines/field * 50 field/second * 3 samples/line = 44100 samples/second
  • 每個 field 294 條垂直掃描線(整張畫面的主動掃描線是 588 條,但全部有 625 條,一樣也是每次只更新半張畫面)
  • 每秒 50 fiels(所以每秒是 25 張)
  • 主要使用在歐洲
  • 歐洲的交流電是 110V, 50Hz

這個其實是相當好的工程範例,說明取捨(trade-off) 的藝術,也因此,當年 Sony 在標準會議上大獲全勝,於是 16 bits 44100 Hz 就 變成了 CD 的標準。1980 年代的日本在電子產業上真是強悍啊。

6 結語

對於數位訊號處理的初學者來說,取樣定理一直都是很難的一個題目,筆者一直都想寫個文章來談談取樣定理,也一直沒有太多心思來思考該如何淺顯的表達。本文的思想實驗是我認為很容易入門的方法,藉由這個思想實驗,讀者可以詳細了解取樣的動作,以及取樣會發生的效果,進而了解取樣定理所要描述的內容。取樣其實還有很多其他的題目可以探討,筆者希望這是一篇能夠讓讀者不至於懼怕取樣定理的一篇文章。

Author: Albert Huang

Created: 2016-05-25 Wed 23:33

Validate

Tuesday, June 30, 2015

如何為 Raspberry Pi 以及 STM32F429 Discovery Board 編譯 RTEMS

如何為 Raspberry Pi 以及 STM32F429 Discovery Board 編譯 RTEMS

如何為 Raspberry Pi 以及 STM32F429 Discovery Board 編譯 RTEMS

-*- truncate-lines: nil -*-

1 前言

上一篇文章講到了如何在 OS X 上編譯 RTEMS 的 toolchain,隔了好一陣子,相信有些人應該已經研究完如何編譯 RTEMS 的 source code, 沒有研究的也沒關係,筆者今天就要來講述一下如何編譯 RTEMS source code 給 Raspberry Pi 或是 STM32F429 Discovery Board 使用。

2 準備檔案

先 checkout RTEMS 的 source code,嗯,git 的動詞是 clone,URL 是 git://git.rtems.org/rtems.git, 請在終端機中輸入以下命令:

$ cd ~/Projects/rtems
$ git clone git://git.rtems.org/rtems.git
Cloning into 'rtems'...
remote: Counting objects: 473959, done.
remote: Compressing objects: 100% (85745/85745), done.
remote: Total 473959 (delta 382898), reused 467269 (delta 377943)
Receiving objects: 100% (473959/473959), 65.15 MiB | 1.33 MiB/s, done.
Resolving deltas: 100% (382898/382898), done.
Checking connectivity... done.

這樣會產生 ~/Projects/rtems/rtems 的目錄

3 Bootstrap

bootstrap script 是拿來產生 configure 檔案的,如果你要修改 BSP 的 configure.ac,就要在執行 bootstrap 之前,或是修改之後,重新執行一次 boostrap

$ cd ~/Projects/rtems/rtems
$ ./bootstrap

這大概要花幾分鐘的時間

4 configure

執行完上一節的 bootstrap 之後,=configure= scripts 就全部都產生完成,現在我們要建立一個編譯的目錄。 RTEMS 分成 build tree 跟 source tree,build tree 就是剛剛 git clone 出來的 ~/Projects/rtems/rtems, 但實際編譯的時候要在另一個 build tree 的目錄,source tree 中各目錄的 preinstall.am 就是拿來產生 build tree 的。 不過現在還不用擔心這件事,先來編譯如下:

$ cd ~/Projects/rtems
$ mkdir build-raspberrypi

或是

$ cd ~/Projects/rtems
$ mkdir build-stm32f4

執行 configure script for Raspberry Pi:

$ cd build-raspberrypi
$ ../rtems/configure --enable-tests=samples \
  --enable-cxx --enable-posix --enable-networking --enable-doc \
  --target=arm-rtems4.11 --prefix=$HOME/Projects/rtems/bsps/4.11 
  --enable-rtemsbsp=raspberrypi

執行 configure script for STM32F429:

$ cd build-stm32f4
$ ../rtems/configure --enable-tests=samples \
  --enable-cxx --enable-posix --enable-networking --enable-doc \
  --target=arm-rtems4.11 --prefix=$HOME/Projects/rtems/bsps/4.11 
  --enable-rtemsbsp=stm32f4

最後你必須看到 available BSPs: raspberrypi 或是 stm32f4 才算是成功,不然無法正常編譯

configure: creating ./config.status
config.status: creating Makefile

target architecture: arm.
available BSPs: raspberrypi.
'make all' will build the following BSPs: raspberrypi.
other BSPs can be built with 'make RTEMS_BSP="bsp1 bsp2 ..."'

config.status: creating Makefile

5 編譯

$ make all

這在筆者的電腦上大約花費三分鐘即可

$ make install

6 文件位置

因為 configure 的時候有帶入 --enable-doc 的參數,所以 doc 也會編譯成功(或失敗),RTEMS 的文件是用 texinfo 寫成,你需要有 texinfo 的環境才能產生 PDF 以及 info 檔,若這邊失敗的話,請重新 configure 並且把 --enable-doc 選項拿掉,再重新 make all 即可。

如果你文件編譯成功的話,info 檔會被安裝到 ~/Projects/rtems/bsps/4.11/share/info, 可以把這個目錄加到你的 info 閱讀器(比如說 GNU Emacs)的目錄中。

至於其他的 dvi, pdf, html, ps 則會在 ~/Projects/rtems/bsps/4.11/share/rtems 目錄下,基本上這些檔案跟 rtems.org 上的是一樣的,直接從 rtems.org 上取得也可以。如果想要發展應用程式,請先找 RTEMS C User's Guide (c_user.pdf),如果想發展 BSP 以及 device driver,則還要搭配 BSP and Device Driver Development Guide (bsp_howto.pdf)。

7 RTEMS BSP 介紹

每一個 BSP 都在 RTEMS source tree 裡面的 c/src/lib/libbsp/$CPU 裡面,Raspberry Pi 以及 STM32F429 Discovery Board 都是 ARM 架構的,因此都會在 c/src/lib/libbsp/arm 裡面。

7.1 Raspberry Pi

c/src/lib/libbsp/arm/raspberrypi/make/custom 目錄下,有好幾個檔案:

$ ls
raspberrypi.cfg  raspberrypi.inc  raspberrypi2.cfg

這底下的命名規則就是 $BSP.cfg, 其中 raspberrypi.cfg 就是給 raspberrypi 這個 BSP 使用的, 而 raspberrypi2.cfg 就是給 Raspberry Pi 2 使用的了。這裡面的設定檔跟 compiler options 有關,舉 raspberrypi.cfg 的內容為例:

#
#  Config file for RASPBERRYPI
#
include $(RTEMS_ROOT)/make/custom/raspberrypi.inc

CPU_CFLAGS = -mcpu=arm1176jzf-s

而 raspberrypi.inc 內容則是:

#
#  Config file for Raspberry Pi variants.
#

include $(RTEMS_ROOT)/make/custom/default.cfg

RTEMS_CPU = arm

CFLAGS_OPTIMIZE_V ?= -O2 -g

# This defines the operations performed on the linked executable.
# is currently required.
define bsp-post-link
    $(OBJCOPY) -O binary --strip-all \
        $(basename $@)$(EXEEXT) $(basename $@)$(DOWNEXT)
    $(SIZE) $(basename $@)$(EXEEXT)
endef

這些都是給 gcc 的參數,或是 bsp link 完成的時候會執行的動作(bsp-post-link),如果你不想要編譯器最佳化的話,可以從這個檔案修改。

7.2 STM32F4

c/src/lib/libbsp/arm/stm32f4/make/custom 目錄下,有幾個檔案:

$ ls
stm32f105rc-testsuite.tcfg stm32f105rc.cfg   stm32f4-testsuite.tcfg  stm32f4.cfg

按照剛剛的規則, stm32f4 自然是使用 stm32f4.cfg 了。

接下來我們來看 STM32F4 BSP 的 configure.ac:

RTEMS_BSPOPTS_SET([STM32F4_FAMILY_F10XXX],[stm32f1*],[1])
RTEMS_BSPOPTS_HELP([STM32F4_FAMILY_F10XXX],[Chip belongs to the STM32F10XXX family.])

RTEMS_BSPOPTS_SET([STM32F4_FAMILY_F4XXXX],[stm32f4*],[1])
RTEMS_BSPOPTS_HELP([STM32F4_FAMILY_F4XXXX],[Chip belongs to the STM32F4XXXX family.])

RTEMS_BSPOPTS_SET([STM32F4_HSE_OSCILLATOR],[*],[8000000])
RTEMS_BSPOPTS_HELP([STM32F4_HSE_OSCILLATOR],[HSE oscillator frequency in Hz])

RTEMS_BSPOPTS_SET([STM32F4_SYSCLK],[stm32f1*],[8000000])
RTEMS_BSPOPTS_SET([STM32F4_SYSCLK],[*],[16000000])
RTEMS_BSPOPTS_HELP([STM32F4_SYSCLK],[SYSCLK frequency in Hz])

這邊可以看到 configure.ac 定義了兩種 BSP variant,分別是 stm32f1*,stm32f4*, 分別會產生不同的 configure 內容, 如果你的 configure 選項給的是 --enable-rtemsbsp=stm32f105rc 就會選擇 stm32f1* 的選項,產生在 ~/Projects/rtems/build-stm32f4/arm-rtems4.11/c/stm32f4/lib/libbsp/arm/stm32f4/include/bspopts.h 裡面,這個之後可能會用到,在這篇文章預先介紹。如果你的版子有不同於預設的振盪器頻率,就需要修改 configure.ac,修改完之後,請重新執行 bootstrap=>configure=>make all=>make install 這個流程。

8 結語

在本文中,筆者介紹了如何下載以及針對 Raspberry Pi 以及 STM32F429 Discovery Board 編譯 RTEMS 的 source code,筆者在我的電腦上兩個都編譯成功,離執行還有點路,基本上筆者在工作場合用的不是這兩個 BSP,所以讀者就跟著我一直來探索吧,下一篇文章就會介紹如何下載 binary 在這兩張版子上並且執行 samples 的測試程式,到時候可能需要修改一些參數,筆者也會一一說明。

Author: Albert Huang

Created: 2015-06-30 Tue 22:31

Emacs 24.5.1 (Org mode 8.2.10)

Validate

Sunday, June 7, 2015

如何在 MacOSX 上安裝 RTEMS toolchain

1 簡介 RTEMS

RTEMS(Real-Time Executive for Multiprocessor Systems) 是一套 open source 的即時作業系統,由 OAR 公司維護,以 GPL license 發行。RTEMS 目前還使用在環繞火星的無線電設備上。

要編譯 RTEMS 必須使用 RTEMS compiler,不能使用 ARM bare metal GCC,所以就來先編譯這些工具吧。

2 環境

筆者的電腦上安裝了 MacPorts,因此這一篇文章是基於 MacPorts 的環境,若完全沒有安裝 MacPorts,環境會更單純一點,安裝過程會很順利,這是由於 RTEMS.org 的測試都預設使用者沒有 MacPorts/Homebrew。

3 如果你已經安裝了 MacPorts,就順便裝這些套件吧

3.1 Xcode

這個 MacPorts 也需要

3.2 Python

python27 或 python34 都可以

3.2 MacPorts 其他套件

$ sudo port install xz cvs

4 決定你的目錄

先決定你的 RTEMS 根目錄,然後分別建立子目錄如下:

目錄 描述
~/Projects/rtems 所有 RTEMS 的根目錄
~/Projects/rtems/compiler RTEMS 編譯器目錄
~/Projects/rtems/rtems-source-builder RTEMS source builder tool
~/Projects/rtems/rtems-git RTEMS git 源碼位置
~/Projects/rtems/bsps RTEMS 的 BSP 放置目錄

5 在 MacOSX 上安裝 toolchain

5.1 git clone rtems-source-builder

$ cd $HOME/Projects/rtems
$ git clone git://git.rtems.org/rtems-source-builder.git

5.2 檢查編譯環境

在命令列下以下的命令檢查環境:

$ rtems-source-builder/source-builder/sb-check

應該會在終端機看到以下的反應:

RTEMS Source Builder - Check, v0.5.0
Environment is ok

5.3 編譯並安裝 ARM cross compiler

rtems-source-builder 會自動抓取 source tarball,編譯,並且自動安裝到指定的 --prefix 目錄。

$ cd $HOME/Projects/rtems/rtems-source-builder/rtems
$ ../source-builder/sb-set-builder \
         --log=build-log.txt \
         --prefix=$HOME/Projects/rtems/compiler/4.11 \
          4.11/rtems-arm

每一組工具的編譯設定稱為 build-set,檔案結尾是 .bset,一般來說是不太會需要碰到這個檔案。4.11/rtems-arm 是指 $HOME/Projects/rtems/rtems-source-builder/rtems/config/4.11/rtems-arm.bset 這個 build-set。

安裝過程前面一小段訊息如下:

RTEMS Source Builder - Set Builder, v0.5.0
Build Set: 4.11/rtems-arm
Build Set: 4.11/rtems-autotools.bset
Build Set: 4.11/rtems-autotools-internal.bset
config: tools/rtems-autoconf-2.69-1.cfg
package: autoconf-2.69-x86_64-apple-darwin14.3.0-1
Creating source directory: sources
......

然後如果你的編譯訊息在這裡結束,那麼你就要參考下一節修改檔案了。

building: arm-rtems4.11-gdb-7.9-x86_64-apple-darwin14.3.0-1
error: building arm-rtems4.11-gdb-7.9-x86_64-apple-darwin14.3.0-1
Build FAILED
  See error report: rsb-report-arm-rtems4.11-gdb-7.9-x86_64-apple-darwin14.3.0-1.txt
error: building arm-rtems4.11-gdb-7.9-x86_64-apple-darwin14.3.0-1
Build Set: Time 0:35:38.935340
Build FAILED

以下是編譯成功的訊息,如果你看到最後訊息是這樣,那恭喜你,ARM compiler for RTEMS 已經結束了。

cleaning: expat-2.1.0-x86_64-apple-darwin14.3.0-1
cleaning: arm-rtems4.11-binutils-2.24-x86_64-apple-darwin14.3.0-1
cleaning: arm-rtems4.11-gcc-4.9.2-newlib-2.2.0.20150423-x86_64-apple-darwin14.3.0-1
cleaning: arm-rtems4.11-gdb-7.9-x86_64-apple-darwin14.3.0-1
cleaning: rtems-tools-HEAD-1
Build Set: Time 0:34:53.361267

5.4 修改 gdb-7-1.cfg

先看剛剛的 error report 說什麼

$ less  $HOME/Projects/rtems/rtems-source-builder/rtems/rsb-report-arm-rtems4.11-gdb-7.9-x86_64-apple-darwin14.3.0-1.txt

錯誤訊息如下:

checking whether to use python... yes
checking for python... /opt/local/bin/python
checking for python2.7... no
configure: error: python is missing or unusable
make[1]: *** [configure-gdb] Error 1
make: *** [all] Error 2

那這是因為安裝 MacPorts 的 Python 而導致的錯誤,如果你打算繼續使用 MacPorts,那就要修改檔案。筆者是透過指定使用系統內建的 Python 而成功編譯,方法如下: 修改 $HOME/Projects/rtems/rtems-source-builder/source-builder/config/gdb-7-1.cfg 找到這一行:

%{!?without_python:--with-python} \

修改成:

%{!?without_python:--with-python=/usr/bin/python} \

你如果在最近這一陣子編譯,可以直接修改 gdb-7-1.cfg 之後再執行 sb-set-builder 開始編譯與安裝的動作,不過如果跟這篇文章的寫作相隔有一段時間,因為 RTEMS 的更新速度很快,筆者建議還是先照原來的方法編譯,若有錯誤訊息再找出解法。

5.5 檢查工具版本

5.5.1 gcc 4.9.2

$ $HOME/Projects/rtems/compiler/4.11/bin/arm-rtems4.11-gcc --version
arm-rtems4.11-gcc (GCC) 4.9.2 20141030 (RTEMS 4.11, RSB 18cea20a12db4d2951e8e8a2dc17fc83c394c1fb-modified, Newlib 2.2.0.20150423)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

5.5.2 gdb 7.9

$ $HOME/Projects/rtems/compiler/4.11/bin/arm-rtems4.11-gdb --version
GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-apple-darwin14.3.0 --target=arm-rtems4.11".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".

5.5.3 測試 gdb 的 python 功能:

$ arm-rtems4.11-gdb 
GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-apple-darwin14.3.0 --target=arm-rtems4.11".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) python
>print('test')
>test
(gdb)

5.6 記得把 compiler 加入你的 $PATH

如果你是使用 BASH,可以編輯 ~/.profile

export PATH="$HOME/Projects/rtems/compiler/4.11/bin:$PATH"

做完之後記得更新 $PATH 並測試 $PATH 是否生效:

$ source ~/.profile
$ arm-rtems-gcc 
arm-rtems4.11-gcc: fatal error: no input files
compilation terminated.

6 結語

RTEMS 是一套很有趣的 open source 即時作業系統,光是應用在航太與武器系統上,就令人眼睛為之一亮了,支援的即時排程演算法也頗完整,有最普遍的 Rate Monotonic Scheduling(RMS), 以及 Earliest Deadline First(EDF) 等等。

本篇文章介紹了如何在 Mac 上編譯 RTEMS 的開發工具,尤其是 gdb,沒有了 Python,gdb 就沒這麼好用,因此筆者花了點時間搞定了 gdb with python 的編譯問題,在這篇文章跟大家分享經驗,接下來筆者將會開始介紹如何編譯 RTEMS source code,請有興趣的人拭目以待。

Author: Albert Huang

Created: 2015-06-07 Sun 21:44

Emacs 24.4.1 (Org mode 8.2.10)

Validate

Wednesday, December 3, 2014

原則導向與規則導向

因為媒體人提到了柯 P 在新聞面對面專訪結束之後,問了「怎麼樣才能勝選但又不用讓馬英九下台」,所以昨夜花了點時間看了柯文哲與連勝文在新聞面對面的專訪,並且比較兩個人的特質。

我想點出來的是,連勝文是規則導向(rule-centered),而柯文哲是原則導向(principle-centered)。比如說講到廉潔,兩邊都有一個故事,連勝文這邊是說他在悠遊卡公司的時候,公司在敦化北路跟民生東路口附近,而他丈母娘的紅豆食府就在附近,但他只要是公司出錢的聚餐,為了避嫌都不會去紅豆食府,乍聽之下,似乎很清廉自持,但後面一點他說了,他悠遊卡董事長上任第一天,有人給了他一本廉政的手冊吧,上面就有提到一個小故事,是說類似的事情,說公司的聚餐不能去認識的人的餐廳裡面等等,也就是說他這個清廉自持的行為是因為有人寫了一個「規則」在哪裡,整場專訪,連勝文也相當強調「依法行事」這件事情,這就是 rule-centered 的行事風格。而柯文哲先生對於廉潔,也有個故事,但是他是講到他在台大人際關係不好的時候提到的,他是說台大醫院開會訂便當的時候,一向是打電話給廠商(比如說抗生素廠商等等)送便當進來,而柯文哲當了主管的第一天就要求屬下不得這樣做,開會一律自己買便當,所以才有 MG149 的私帳(因為這些都得自己出錢,但又需要管理,其實就是類似班費)。看得出來,柯文哲是在群體壓力下,堅守一個原則,而不是依照既有規則來行事。另外,講到說實話這件事,他非常堅持誠實這個原則,所以當他發現他講真話(失言風波),媒體很反彈,他說他回去苦惱了很多天,最後想說這跟道德也沒什麼關係,只是尊重聽這些話的人,所以他就做了修正。像這一類行事方法,就是原則導向,亦即心中有一些原則,是大方向,面對每天不同的事件發生的時候,依據這些心中的原則來行事,而且會有優先順序的。

規則導向的行事風格不會出什麼大錯,行事很安全,但有時候會不通情理,比方說有個丈夫因為妻子羊水破了,要趕緊到醫院生產,於是一路超速,警察把他攔下來發現他是因為妻子要生產才超速,規則導向的人這時候就會堅持說你犯了法,必須要開單,因為要依法行事,然後依法也沒規定警察必須要護送孕婦,於是就不理他。這就是規則導向的行事風格。原則導向的行事風格的警察,在攔下來發現超速的原因之後,會衡量各種原則,發現生命當然是優先的,於是罰單也不開,而且還護送這台車一路到醫院。事後來看,後面那個警察做的事情對嗎?的確有人超速而不開單,那麼他是不是包庇違法的事情發生呢?如果有人不問當時發生的狀況與當事人應對的方式,只挑出部份的違法證據來指控對方違法,就落入了規則導向的方式。

原則導向也是兩個當中,能夠開創新局的方式。如果面對一個全新的領域或全新的世界,既有的規則都不能應用,一個規則導向的行事風格就會陷入混亂當中,因為完全沒有規則可循,或是隨便引用相近的陳舊規則來應用在全新的事情上面,這是不是很熟悉?這就是近十幾年來,陳舊的法規面對全新的世界的時候的混亂。以原則導向來說,就會像美國憲法這樣,先條列出行事的原則,而當有任何新的事件發生,就回去檢視這些原則,仔細考量,最後選擇這個新事件要怎麼處理,如此才能夠面對瞬息萬變的世界,而通常這些原則就是一個團體、個人要堅守的價值。

原則導向有個很重要的人一定要提,那就是富蘭克林(Benjamin Franklin, 1706--1790)在他的自傳提過他隨身帶了一本小冊子,稱之為 "The Little Book",上面列了十三條原則,每週選定一個原則來強化,但每天晚上都會針對這十三條原則檢討自己當天的行事是否遵循了這些原則。沒有遵循的地方檢討原因是什麼,但不過分責備自己。注重長期來說,是否有進步。富蘭克林後來說了 "Tho’ I never arrived at the perfection I had been so ambitious of obtaining, but fell far short of it, yet I was, by the endeavour, a better and a happier man than I otherwise should have been if I had not attempted it. " 富蘭克林的這句話是說,他從未達到他原來所想要達到的完全,但是透過熱切的追尋,他變成一個比未追尋完全之前更好更快樂的人。只有這樣子才能夠進步。在 Stephen Covey 的書[3] 「與成功有約」裡面則是把富蘭克林的方法進一步加一些改變並且仔細的闡述,對原則導向有興趣的人可以參考一下。

規則導向我想到的代表人物是馬英九總統,看他的行事風格你就會知道什麼叫做規則導向,他最常把「依法行事」掛在嘴邊,對於一些大家都知道要為大原則放棄追小錯的時候,他只會專注在那個錯誤之上。所以規則導向就是在任何事情發生的時候,一定是檢討有沒有違反規則,並且對違反規則耿耿於懷。因為犯錯就是犯錯,沒有什麼逐漸改善讓犯錯率變少這件事。這是因為規則導向常常會有非常多的規則,而且是針對非常明確的事情做規範,比方說全勤獎金就是個很規則導向的事情,全勤的定義是你這個月每天都到,如果你有一天因為生病而沒到,就是沒有全勤獎金,不論你缺席的理由是什麼。但是原則導向就會去思考,全勤的意義是什麼?然後可能思考出全勤的意義在於你對於公司的貢獻,所以訂定了工作進度,只要你每個月達到工作進度就獎勵,而你中間是否因病缺席,就不在考量範圍內。

寫了這麼多,簡單總結一下,原則導向就是望向未來,而規則導向就是依循過去。 我不是在講哪一個個人怎麼樣,而是哪一種行事方法能夠帶領個人、公司、社會,甚至國家往未來瞬息萬變的挑戰,其實很清楚。

[1] 柯文哲專訪 柯文哲專訪
[2] 連勝文專訪 連勝文專訪
[3] Stephen Covey, "The 7 Habits of Highly Effective People" (中文翻譯:與成功有約)

Thursday, August 7, 2014

LaTeX 字型安裝筆記: Adobe Garamond Pro 字型



LaTeX 字型安裝筆記: Adobe Garamond Pro 字型









LaTeX 字型安裝筆記: Adobe Garamond Pro 字型



上一篇文章筆者提到了 Garamond 字型有非常多個供應者, 其中一個就是 Adobe Garamond Pro 字型, 這是 Adobe 公司出品的商業字型, 在 LaTeX 上同樣也是由 mathdesign 這個套件來支援。




筆者先假設你購買或從他處取得 Adobe Garamond Pro 的以下檔案:



  • AGaramondPro-Regular.otf

  • AGaramondPro-Italic.otf

  • AGaramondPro-Semibold.otf

  • AGaramondPro-SemiboldItalic.otf




請把以上這些檔案複製到 $TEXMF/fonts/opentype/garamond/Adobe Garamond Pro 的字型目錄裡面, 在筆者的 Mac 上我把他們複製到 ~/Library/texmf/fonts/opentype/garamond/Adobe Garamond Pro 裡, 然後執行 sudo texhash 更新系統路徑。




使用的方法是:




\usepackage[adobe-garamond]{mathdesign}




然後你就可以在 LaTeX 裡面使用 Adobe Garamond Pro 這一套商業字型了, 有任何其他的使用細節, 可以在 CTAN 上搜尋 mathdesign 套件 的說明檔案。




P.S.: 這樣安裝的 Open Type 字型只可以使用在 PDFLaTeX 上, LaTeX->DVIPS 這個路徑需要其他的安裝方法。




Author: Albert Huang


Created: 2014-08-07 Thu 01:39


Emacs 24.3.1 (Org mode 8.2.1)


Validate





Wednesday, August 6, 2014

LaTeX 字型安裝筆記: URW Garamond 字型



LaTeX 字型安裝筆記: URW Garamond 字型








LaTeX 字型安裝筆記: URW Garamond 字型



Garamond 是一種描邊字型家族, 泛指由法國的鉛字鑄造師 Claude Garamond~(c. 1480–1561) 設計的字型或後人衍生的字型。許多與 Garamond 有關聯的字型則出自於另一位鉛字鑄造師 Jean Jannon。Garamond 同時也是印刷的時候, 最省墨水或碳粉的字型。1

Garamond 字型有非常多提供者, 有基於 Garamond 設計而衍生的: Adobe Garamond, Garamond Premier, Sabon, EB Garamond, URW++ Garamond No. 8 或是基於 Jannon 而衍生的: ITC Garamond, Garmond 3 等字型, 其中我們今天要講的是 URW++ 所製作的免費 Garamond 字型, 這個字型被內建在 Ghostscript 程式套件裡面, 並且被 TeX 社群引入到 LaTeX 字型中, 其格式是 PostScript Type1 格式。要使用這個字型, 你必須先安裝 mathdesign 這個套件。
使用方法如下:



\usepackage[urw-garamond]{mathdesign}
\usepackage[T1]{fontenc}

如果你無法使用, 別急, 很可能是你的 TeX 系統沒有附上這套字型, 雖然這套允許非商業用途免費使用, 但 TeX 不一定會附上, 你可以到 CTAN Garamond 網頁 下載所有的 afm 以及 pfb 檔, 並且放置在正確的路徑上, 筆者把 *.afm 放到 ~/Library/texmf/fonts/afm/urw/garamond 裡, 並且把 *.pfb 放到 ~/Library/texmf/fonts/type1/urw/garamond 裡面。筆者的電腦是 Mac, 其他系統請參考相關 TeX 系統的說明。放完之後要更新路徑, 讓 TeX 系統能夠使用這些字型, 只要在終端機輸入 texhash 即可。

URW++ Garamond 是一套附有數學符號的描邊字型, 除了有最省墨水或碳粉之外, 也被認為是可讀性很高的一個字型, 如果你已經厭倦 Times Roman 字型, 不妨可以來試試這一套字型。



Author: Albert Huang

Created: 2014-08-06 Wed 22:29

Emacs 24.3.1 (Org mode 8.2.1)

Friday, August 1, 2014

在 LaTeX 使用內建在 Acrobat Reader 裡的 Minion Pro 與 Myriad Pro 字型以及 =\epsilon= (\epsilon) 與 =\ell= (\ell) 的問題解法





在 LaTeX 使用內建在 Acrobat Reader 裡的 Minion Pro 與 Myriad Pro 字型以及 <code>\epsilon</code> (ε) 與 <code>\ell</code> (ℓ) 的問題解法









在 LaTeX 使用內建在 Acrobat Reader 裡的 Minion Pro 與 Myriad Pro 字型以及 \epsilon (ε) 與 \ell (ℓ) 的問題解法





1 前言




Minion Pro1 是一個 Adobe 出品的 Serif 字型, 內建在 Adobe Reader2 與 Adobe Acrobat 裡面, 是一套高品質且漂亮的字型, Myriad Pro3 則是同樣內建在軟體內的 Sans Serif 字型。有興趣的讀者可以先到 footnotes 上去找兩套字型的範例。兩套字型的格式都是 Open Type, 而且免費贈送, 如果我們想要在自己的 LaTeX 檔案裡面使用, 要怎麼安裝呢?以下這篇文章就會介紹安裝過程以及這兩套字型相關的問題與解法,所有範例都是以 MacOSX 為主, 其他系統請自行找尋相關資源。






2 準備檔案




  • TeX 系統



你必須先安裝好 TeX/LaTeX 系統, Windows 的話一般是 MikTeX 比較受歡迎, 而 Mac 則是 MacTeX, 兩者都是基於 TeXLive 衍生出來的, 如果是 Linux 使用者的話, 就直接安裝 TeXLive 即可。




  • MnSymbol 套件



安裝完 TeX/LaTeX 系統之後, 用系統附的套件管理員安裝 MnSymbol 這個套件。MnSymbol 是搭配 MinionPro 使用的數學符號字型, 相關的符號可以參考 4 裡面的說明檔。




  • LCDF typetools




一般來說安裝完 TeX/LaTeX 系統後就會有 LCDF typetools 了, 你可以在終端機下命令檢查:



Aquila:Font albert$ otfinfo --version
otfinfo (LCDF typetools) 2.100
Copyright (C) 2003-2013 Eddie Kohler
This is free software; see the source for copying conditions.
There is NO warranty, not even for merchantability or fitness for a
particular purpose.


如果沒有的話, 請用套件管理員或請到 LCDF Type Software 下載安裝。




  • CTAN 上的 MinionPro 套件



如果 TeX/LaTeX 套件管理員沒有列 MinionPro, 那麼就請你到 CTAN 下載以下檔案:



  1. http://mirrors.ctan.org/fonts/minionpro/enc-2.000.zip

  2. http://mirrors.ctan.org/fonts/minionpro/metrics-base.zip

  3. http://mirrors.ctan.org/fonts/minionpro/metrics-full.zip

  4. http://mirrors.ctan.org/fonts/minionpro/metrics-opticals.zip

  5. http://mirrors.ctan.org/fonts/minionpro/scripts.zip


  6. Minion Pro 與 Myriad Pro 字型檔



在你安裝完 Adobe Reader 或 Acrobat 之後, 你就會在 /Applications 有一個 "Adobe Reader.app" 而 Minion Pro 與 Myriad Pro 字型檔會放在 /Applications/Adobe\ Reader.app/Contents/Resources/Resource/Font/ 裡面



Aquila:~ albert$ cd /Applications/Adobe\ Reader.app/Contents/Resources/Resource/Font/
Aquila:Font albert$ ls
AdobePiStd.otf MinionPro-BoldIt.otf MyriadPro-Regular.otf ZY______.MMM
CourierStd-Bold.otf MinionPro-It.otf SY______.PFB ZY______.PFB
CourierStd-BoldOblique.otf MinionPro-Regular.otf SY______.PFM ZY______.PFM
CourierStd-Oblique.otf MyriadPro-Bold.otf ZX______.MMM
CourierStd.otf MyriadPro-BoldIt.otf ZX______.PFB
MinionPro-Bold.otf MyriadPro-It.otf ZX______.PFM



如果你安裝的是 Acrobat, 那麼把 /Applications 下的 Adobe Reader.app 取代成 Acrobat.app 即可。先把這個路徑記起來, 等一下會用到。





3 安裝




檔案準備完之後, 就要開始安裝過程了, 筆者先認定你已經會操作終端機, 如果不知道的話, 請在網路上搜尋終端機的使用方式, 請先開啟終端機(or Terminal.app)。




先切換使用者目錄到 scripts.zip 解壓縮的地方, 一般會在 ~/Downloads/scripts 裡面:




Aquila:~ albert$ cd ~/Downloads/scripts/
Aquila:scripts albert$ cp /Applications/Adobe\ Reader.app/Contents/Resources/Resource/Font/*.otf ./otf
Aquila:scripts albert$ ./convert.sh
Creating PostScript fonts ...
AdobePiStd: has no 'j' glyph to make dotless
cfftot1: glyph 'sterling.oldstyle': While processing otf/MinionPro-Bold.otf:
cfftot1: glyph 'sterling.oldstyle': warning: complex flex hint replaced with curves
cfftot1: (This Type 2 format font contains flex hints prohibited by Type 1.
cfftot1: I've safely replaced them with ordinary curves.)
MinionPro-Bold: already has a dotlessj glyph at 'uni0237'
MinionPro-BoldIt: already has a dotlessj glyph at 'uni0237'
cfftot1: glyph 'colonmonetary.oldstyle': While processing otf/MinionPro-It.otf:
cfftot1: glyph 'colonmonetary.oldstyle': warning: complex flex hint replaced with curves
cfftot1: (This Type 2 format font contains flex hints prohibited by Type 1.
cfftot1: I've safely replaced them with ordinary curves.)
MinionPro-It: already has a dotlessj glyph at 'uni0237'
MinionPro-Regular: already has a dotlessj glyph at 'uni0237'
Aquila:scripts albert$ mkdir -p ~/Library/texmf/fonts/type1/adobe/MinionPro
Aquila:scripts albert$ cp ./pfb/*.pfb ~/Library/texmf/fonts/type1/adobe/MinionPro



然後解壓縮字型相關檔案



Aquila:scripts albert$ cd ~/Library/texmf
Aquila:scripts albert$ unzip enc-2.000.zip
Aquila:scripts albert$ unzip metrics-base.zip
Aquila:scripts albert$ unzip metrics-full.zip



更新字型地圖,



Aquila:scripts albert$ updmap


執行的結果應該會列出 ~/Librar/texmf/fonts/map/dvips/MinionPro/MinionPro.map 以及 ~/Librar/texmf/fonts/map/dvips/MyriadPro/MyriadPro.map




找到之後, 預設是 disable 的, 你要下命令啟動他們:



Aquila:scripts albert$ updmap --enable Map=MinionPro.map
Aquila:scripts albert$ updmap --enable Map=MyriadPro.map



到這邊如果安裝過程順利沒有什麼錯誤的話, 這兩套字型就算是安裝完成了。





4 使用




想要在你的 LaTeX 檔案裡面使用 MinionPro 字型, 只要在 preamble 寫下:




\usepackage{MinionPro} % 使用 Minion Pro 字型
\usepackage{MnSymbol} % 使用搭配 MnSymbol 的數學字型




另外, 預設的 text figure 一般人可能不太習慣, 可以選擇 lining figure 如下:




\usepackage[lf]{MinionPro} % 使用 Minion Pro 字型, lining figure




兩者的差異如圖所示:





MinionPro-figures.png





其他更詳細的使用方法, 請參考 CTAN 連結上面的 MinionPro.pdf 檔案。安裝過程就介紹到這裡了。






5 \epsilon 變成方塊的問題




有數種解決方法, 不過最簡單的是用 \varepsilon 取代, 或是在 preamble 設定




\renewcommand{\epsilon}{\varepsilon}





6 \ell




Adobe Reader 9 之後 \ell 被更改編碼位置, 但是 enc-2.0.0 未反映這個更新, 要修正這個問題, 就請修改 base-MinionPro-ab.enc 這個檔案, 他應該在 ~/Library/texmf/fonts/enc/dvips/MinionPro 裡面, 打開檔案後, 把 "afii61289" 取代成 "uni2113" 然後存檔即可。





7 結語




TeX/LaTeX 是一個高品質的排版系統, 桌上型排版發展了這麼多年, 一直還沒有任何其他排版軟體能夠真正的取代它的地位, 雖然學習曲線比較陡峭, 但依然值得我們花精神學習它。LaTeX 的字型安裝一直是令人頭痛的問題, 這篇文章簡單的介紹如何安裝 Minion Pro 與 Myriad Pro 兩套字型, 讓使用者在 LaTeX 使用它們, 希望能夠減緩一些安裝字型時頭痛的程度, 讓各位更能享受 LaTeX 的排版品質。






Author: Albert Huang


Created: 2014-08-01 Fri 23:58


Emacs 24.3.1 (Org mode 8.2.1)


Validate





Monday, March 3, 2014

漫談分貝(dB) 這一堆玩意兒

今天是 3 月 3 日, 恰好是發明電話的貝爾的生日, 所以今天我們來談以貝爾的姓氏命名的單位, Bel 以及 decibel(分貝或 dB)。剛開始接觸數位訊號處理或是通訊領域, 最常令人困惑的就是 dB 這個玩意兒, 它既不是一個單位, 也不怎麼直覺, 接下來就讓我們來看看這玩意兒吧。

分貝(dB, or decibel) 當初是拿來描述量測的電話線訊號衰減量, 在 1928 年貝爾系統公司(貝爾電報電話公司的相關企業)把原本使用的 Transmission Unit(TU) 改名為 decibel, 並且增加 Bel(1 Bel = 10 decibel), 用來紀念發明電話的貝爾(Alexander Graham Bell, March 3, 1847 – August 2, 1922),1 文章發布的今天剛好是他的生日。

分貝是拿來描述衰減量的, 只是一個相對單位而已, 就像一般講的數量級一樣, 一個數量級代表的是十倍, 而 1 Bel 就是 10 dB, 是由以 10 為基底的對數函數產生:

\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} \end{equation}

要先記住上述衰減量是拿來描述功率衰減的, 我們也可以用 dB 描述振幅的衰減量, 而初學者很容易搞混計算功率以及振幅衰減的分貝公式。

功率:

\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} \end{equation}

振幅(如電壓、電流、聲壓):

\begin{equation} L_{dB} = 20~\log_{10} \frac{A_1}{A_2} \end{equation}

只要先記得分貝都是計算功率的公式, 再利用電路的基本公式: \(P=IV=\frac{V^2}{R}\), P 為功率, I 為電流, V 為電壓, R 為電阻, 那麼:

\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} = 10~\log_{10} \frac{V_1^2}{V_2^2} = 20~\log_{10} \frac{V_1}{V_2} \end{equation}

而大部分功率都是振幅的平方倍, 所以都可以得到上述的式子, 因此振幅計算公式前面的常數是 20。

當倍數轉換成分貝讓乘法轉換成加法, 除法轉換成減法, 使得運算更為簡單, 其數值也不容易超過能夠表示的範圍。例如接收機的情況, 從發射機一路到接收機的各級增益, 按照順序列表:

  • 發射機 \(P_{TX} = 1W = 10\log_{10} \frac{1W}{1mW} = 10\log_{10} 1000 = 30 dBm\)
  • 發射天線增益 \(G_{TXANT} = 10 dBi\), 或 10 倍
  • 空氣中衰減 \(ATT_{channel} = -60 dB\), 或 1/1000000 倍
  • 接收機天線增益 \(G_{RXANT} = 10 dBi\), 或 10 倍
  • 接收機 LNA 增益 \(G_{RX} = 20 dB\), 或 10 倍

計算各級增益, 以 dB 來計算,只要算

\begin{equation} RSSI_{dB} = P_{TX} + G_{TXANT} + ATT_{channel} + G_{RXANT} + G_{RX} = 30 + 10 - 60 + 10 + 20 = 10 dBm \end{equation}

而用倍數來計算則會是這樣:

\begin{equation} RSSI = 1 * 10 / 1000000 * 10 * 10 = 0.001 \end{equation}

可以看出用倍數算會出現動態範圍比較大的整數或小數, 而 dB 值只要加加減減就出來了, 這在浮點運算的時候看不出好處, 但在定點運算上可以看出來上述的例子, dB 的計算只要給有號整數部分 8 個位元即可表示, 而線性尺度(linear scale, 也就是上述所稱的倍數) 的計算則會做到超過 20 位元的除法。

除了運算上會變得動態範圍變小以外, dB 公式中的對數函數也有將比較小的數值變化放大並將比較大的數值變化縮小的功用。

Resp_linear.png

Figure 1: 線性尺度

Resp_dB.png

Figure 2: dB 尺度

可以看得出來 320kHz 以下的變化原本在線性尺度看不太出來, 但在 dB 尺度看出來上下變化範圍有 10 dB 的大小, 這對訊號來說已經算是不小的影響。而線性尺度看起來差異很大(一半)的 400kHz 到 900kHz 的範圍, 在 dB 尺度上只有 4 dB 左右, 320kHz 變化 10 dB 在這個例子中, 因為那不是我們要的訊號, 所以影響不大, 但若發生在我們想要的頻譜上, 線性尺度可能就會看不太出來, 這個是 dB 尺度的優點。

以上就是對於 dB 簡單的介紹, 那麼我們常常看到 dB 後面還加上一些字母, 那是什麼意思呢?我們來看一些常用的 dB 家族。

分貝後面如果加上了其他的字母, 代表分母的參考量, 就會從相對值變成絕對值。

  • dBm 代表分母是 1mW, 所以 \(dBm = 10~\log_{10} \frac{P}{1mW}\)
  • dBW 代表分母是 1W, 所以 \(dBW = 10~\log_{10} \frac{P}{1W}\)

如果是分貝後面加上其他字母, 但是該字母被括號刮起來, 是代表訊號的種類。

  • dB(A) 代表聲壓, 是一個絕對單位, 參考訊號位準是 \(20~\mu~Pa\),2 是人耳所能聽到的下限, 又因為聲音是振幅, 所以計算公式為:
\begin{equation} L_p = 20~\log_{10}\frac{P_{rms}}{P_{ref}}, P_{ref} = 20~\mu~Pa \end{equation}

聲音用 dB 來表示是因為耳朵對於壓力變化大小是對數級的, 至於頻率變化也有類似的關係, 因此對於噪音計算定義了 octave band filter, 每一個 octave band 的中心頻率是下一個 band 的 2 倍或 1/2。3

dBi 是用來描述天線增益, 定義是最大的波束相對於理想均勻球體輻射樣式(isotropic) 的增益。

dBm/Hz 則是拿來描述功率密度(power spectral density), 意思就是每 1 Hz 所含的功率, 如果你有功率密度 -30 dBm/Hz, 在 10 MHz 寬度上都是平坦的, 其他地方的數值都小到可以忽略, 那麼總發射功率就是 \(-30 + 10 \log_{10} {10 \times 10^6} = 40 dBm = 10W\)

我們描述 SNR(訊雜比) 的時候也常常用 dB 來描述, 大部分的接收機, 比如說 Wifi, Bluetooth, LTE, WCDMA 等等都會顯示 SNRdB, 而筆者常常看到有人引用這個 SNR 值的時候, 忘記加上 dB, 這樣會造成非常大的誤解與巨大的差異, 舉例來說, 如果 SNR 是 60 dB, 而引用的時候說 SNR 是 60, 那麼這個意思就是 \(\frac{P_{signal}}{P_{noise}} = 60\) 了, 而 \(60~dB = 10^{\frac{60}{10}} = 1000000\), 差距有 \(\frac{1000000}{60} = 16666.7\), 有上萬倍的差異啊!筆者知道分貝對初學者來說, 是個不容易搞懂的數量, 因此寫了這篇文章, 希望大家在接觸訊號與通訊領域的時候, 看到 dB4 能夠不再那麼陌生。

Author: Albert Huang

Created: 2014-03-03 Mon 21:47

Emacs 24.3.1 (Org mode 8.2.1)

Validate