zero

I've recently switched my laptop to OpenSUSE MicroOS. I can talk about it all day but I'm here to talk about one thing today.

Discord seems to always show a red banner saying the installation is corrupted (does not matter if it is flatpak, AppImage or else) and the help link is unhelpful as it only describes Windows.

After turning on the inspector tools, I found the real problem being it wasn't able to load the Discord voice module.

It turns out it was the SELinux that is causing issues. All you need to do is to run sudo setsebool -P selinuxuser_execstack 1 (src: this reddit post).

That's it for today.

After getting my pilot's license, I still feel very much like a noob. There's just a lot of things that doesn't get covered during regular training: extended cross-country flight planning, mountain flying, landing at a high elevation airport and take-off and landing in an actual busy/international airport (a.k.a. the airports everyone actually knows or as pilots call them, Class Bravo Airports).

I found out about this group on the FAAS website. After listening to the talk, thinking I can at least steal some trip ideas and planning ideas out of it, I found out we can actually make this work even I'm not a member of that flying club, I've decided to actually join the group, actually fly to those locations, practice those advanced topics!

The Trip

This is a huge 4 days trip. We depart San Carlos, went to a small airport called Kern Valley before ending the first day in Palm Springs. We visited the famous Sedona Airport and Monument Valley Airport the next day. The third day is a fun sightseeing day, Grand Canyon airport and SFRA, Zion National Park, Hoover Dam before landing in KLAS. Finally, we visited Furnace Creek (-210 MSL!) and Paso Robles for some lunch before coming back.

The group met up a couple days before to went over some routing options and leg assignments (we flew with 2 pilots + 1 CFI onboard, so we need to decide who flies which leg). We originally planned to go to Catalina Island and San Diego on Day 1 and Mammoth Lake on the last day. However, the weather was not good enough for those two days so we ended up with the route we have now. (Catalina was low IFR and Mammoth Lake had thunderstorm forming around it as we get closer.)

Since we're flying very close to max gross weight and we had to cover long distance, we have to plan the fuel requirements and stops very closely. Cessna 182 also have a difference in Maximum Take-Off Weight and Maximum Landing Weight, so we need to also have that in mind when planning how much fuel to load. Nothing too crazy, but just a bit of extra verification needed before each trip and fueling.

The weather briefing is also important. I knew we have radar image on FIS-B over ADS-B, however, I never really needed to check it in-flight and we had plenty reasons and opportunity to use it in this trip. The reason behind checking weather forecast products also become crystal clear this time as we'll be covering a huge area, we need to know how clouds and thunderstorms are forming and moving. These are just a couple things that did not click or make sense as a PPL who only flew locally — the weather tends to be pretty predictable and well-known and we only need to check a small area.

Let's talk about a few interesting airports:

L05 – Kern Valley

Kern Valley is a beautiful small airport. It even has a small dog park on the field (but I mean the dog kinda can just ... walk the airport right? 😅). Sadly the cafe was not open that day and the potty was a bit... needing maintenance.

Approaching L05 Airport

The airport is situated in a narrow valley on one side with some mounds on the other side. My dumbass was a bit too much distracted by the mounds and decided to turn a bit early, which put us high. I used forward slip to get us down there without gaining too much speed but we did land a little bit fast (~78 kts) but it was at least a smooth landing! Reflecting on it now, I probably should've just extend the downwind past the mound and take my time to do a longer final approach.

KPSP – Palm Springs

Approach View of Palm Springs Airport

PSP is a Class Delta airport with a TRSA around it. It didn't feel any different to me as we were already on Flight Following with LA Center. We just following the instruction of the ATC and switch to PSP tower. We were given a right downwind 31R entry. Did you spot where the airport is in the picture above? Well, I didn't, the runway became much more clearer as we turn base. It just blends into the nearby city and desert too well. (Tip: The air museum is where the airport is!)

Runway 31R is the smaller runway closer to Atlantic Aviation which is the FBO we used over there. Watch out that this airport has arrival alert, Runway 31L/R and Taxiway C can be confused.

The airport is otherwise not too different but we were surprised to find out that on Thursday nights, Palm Springs downtown hosts a street festival which made the short overnight stay fun for us!

KSEZ – Sedona Airport

View of Sedona Airport

Sedona is a beautiful uncontrolled airport on a tabletop mesa. It does make you feel funny because when you're landing Runway 21, not only do you need to worry about the mountain right before the approach end but also the fact that approach end itself is a cliff. The airport is otherwise gorgeous and has a great view of the nearby area. Read the noise abatement procedure before you head in as the airport is right in the center of Sedona.

We didn't get to walk the trail that day due to developing weather but there is a trail around the airport. There is also a great restaurant on the field called Mesa Grill.

UT25 – Monument Valley

View of Sedona Airport

Such a fun airport to come into: one-way in/out, high elevation and narrow runway. UT25 is a private airport so prior authorization is required to land here. However, if you're a guest of the lodging nearby, I don't think there's going to be much of an issue getting a permission here. This is an one-way in, one-way out airport with a 45ft narrow runway, in fact, this is the narrowest runway I have ever landed on! The other side of the airport is a cliff, so you'll be landing 16 and departing 34. If you do need to go-around, do it early.

The runway itself is well-maintained, paved and sloped up 2.4deg on 16 which helps with slowing the airplane down. Make a stabilized approach and don't be surprised if your main gear touched down earlier than you expected (since it is an upslope) and maintain the centerline. It felt like quiet an accomplishment when I did it. I'm sure this is nothing for experienced pilots but for a month-old wet PPL holder, it felt like a strong confidence booster for myself.

Once landed, taxi off the runway to a dirt/stone parking area. Use soft-field techniques to taxi to avoid chipping your propeller, and ... treat yourself to the beautiful views around the valley! (The lodge nearby provides free shuttle service to and from the airport. They also have fun tours of the valley!)

Grand Canyon SFRA (Special Flight Rule Area)

Grand Canyon SFRA chart

Grand Canyon is a hotspot for air tour operations so there are actually a specific routes assigned to air tours and general aviation. You can find the specific FAR here. The basic idea is you have to fly 10,500 MSL and above and monitor/announce on a specific channel depending on which sector you're in. There are also a specific altitude to fly if you're in one of the corridor. Note that flight following is also available here through LA Center but you do need to still monitor/announce on the local channel as well.

There is an airport (KGCN) here as well if you need fuel and bathroom, note the high level of helicopter traffic here. There is a FAA “From the Flight Deck” video for this airport. (Sidenote: I love this series of videos. I always check it before I go to a new airport, it gives you a quick overview of the airport, things to look out for (like arrival alerts) and sometimes approach tips too.)

KLAS – Las Vegas Henry Reid International Airport

Approach View of Las Vegas Henry Reid Airport

Another highlight of the trip! This is going to be my first landing in a Class Bravo airport. What is special about a Class Bravo airport? Uh, well I guess not that much really. 😅 However, for a pilot, going to where those big bois (airliners, jets, etc...) are, is pretty cool. Big airport sometimes also have much more expensive landing fee as well, SFO, for example, is ~$500 if you land there even in a single piston (aka small) airplane IIRC. We first head to Hoover Dam to do a tour, the Vegas approach was helpful and told us to stay outside of Bravo and let them know we're ready to head inbound, and to fly a south heading first. (Sidenote: Don't tell ATC you're going to Las Vegas since there are 3 airports around the area. ATC will ask you to confirm if it's Henry Reid, probably because not that many small airplanes go there.)

Once we called our inbound and fly the initial heading, they sent us to the south and basically fly a big downwind for 19L. 19R was closed for the day and there were also a NOTAM saying transient GA might not be allowed. We did made a reservation with Atlantic first so we were not expecting problems. (There are both Atlantic and Signature on the field, they're both next to the taxiway Hotel and on different end of the airport (North – Atlantic / South – Signature). If you're going to FBO, you're probably going to land on 19s because it's much closer and you usually see commercial traffic on 26s.

After the big downwind, we were restricted to 3500ft until 3nm final due to helicopter traffic, so time to pull another forward slip. (Because we're going to Atlantic which is on the approach end of 19 anyway, I didn't plan to land fast and long, but if you're going to Signature that might just work since 19L is 9771 feet long anyway! Note that after landing, the taxi instructions might be longer than what we've been accustomed to since there are multiple runways and taxiways (especially crossing runways is not a thing at the most airports I go to).

The Atlantic FBO is probably the best looking FBO I've ever seen, shiny building with a lot of amenities. I definitely felt under-dressed as every single pilot is in their uniforms. 😅

L06 – Furnace Creek & KBTY – Beatty

Furnace Creek (L06)

Furnace Creek is kind of famous. It is in the Death Valley National Park and the airport has a elevation of -210 MSL. Yes, minus, it is under the mean sea level! The airport is under a MOA so a bit of checking and altitude planning might be required depending on if MOA is active. Unfortunately, after two low passes, we've decided that the surface is a bit too rough and not to land there. With some proper soft field landing techniques, it is possibly fine to land on it but we really don't want to risk popping a tire out in nowhere. We diverted to Beatty which is just across the ridge for a quick rest stop. (I felt a bit nauseating at the point as a passenger as well. It usually isn't that big of a problem if I'm flying myself, but as a passenger, I do sometimes feel nauseating if it is too turbulent.)

Beatty is a small single runway airport, they do have fuel services and potentially a crew car and apparently some glider activities around it too. It also has a very clean potty, so highly recommended if you need a quick stop en route!

China Lake Airport

After that, we decided that going to Mammoth Lake is too risky due to a thunderstorm developing up there and we did not want to risk having to fly all the way back out again. We got cleared through R-2505 at or above 10,000 MSL, that means we get to flyover the China Lake NAWS, apparently it is where our Navy test new weapons and jets.

KPRB – Paso Robles

Our last stop before heading back to San Carlos. Paso Robles' transient parking is right across the terminal on the left side. FBO was very nice and has free crew car for 2 hours. We took the cars and head into downtown for some delicious taco before heading back. We flew by the Pinnacles National Park but I think this park is one of those that is better appreciated on the ground as it features a very cool cave systems.

After that, not much happens, we flew by E16 and asked NorCal for flight following to KSQL. They cleared us through Moffett and Palo Alto Delta automatically. (which is rare, I usually get a frequency switch to Moffett tower and they pass me to Palo Alto and San Carlos) It makes the entire way super easy, we landed in San Carlos and ended this wonderful trip.

Thoughts

As I said earlier, I felt as a fresh Private Pilot, there were so many things that just isn't obviously clear to me about how to do it and why to do it. Plan for a long XC trip like this and get to land on big airports and high elevation airports really helps building confidence, knowing that I can actually do these as well.

It really also made me to have a newfound appreciation of the US. There are so many places that is pretty hard to reach by airlines + car (like Monument Valley for example), however, it is relatively easy to reach via a small airplane. I would love to explore more of those places in the future!

Thanks to San Carlos Flight Center to organize this trip!

This is an article about my experience learning how to fly an airplane. Given it's rare in Taiwan to have a chance to learn general aviation, I'm gonna write this article in Traditional Chinese instead, an English version might come later.

上一期之後,就是漫長的等待,因為考官突然莫名的難找。那陣子灣區的天氣有點糟,加上有個 DPE (指定飛行員考官) 突然暫停接受新預約,導致那陣子所有附近 DPE 的排程都排了兩三個月(我甚至看過半年的)。我總之是先約了,但中間就陸陸續續 Solo 個幾次,跟我教練一個月飛一兩次模擬考,甚至無聊到開始學轉換到大一點的飛機 (Cessna 182) 跟山區飛行。就跟所有故事一樣,一但你開始手癢想做別的事情,事情就會突然發生。突然有個考官問我說,下週四如何?「好啊!我要了!」我趕快回覆了考官,一邊趕快臨時抱佛腳約了我教練考前練習,一直到考前我的 soft-field landing 跟 short-field landing 都還不是很好。甚至我考前還多約了其他 CFI 來練習,但總之考試日不到一週,很趕。

4/20 第一次考試(失敗)

我考前一天約了教練做練習,但我們只有練習到 soft-field landing,因為時間因素,那天做了一個 short-field landing 就收工了。雖然那個有到位,但我還是滿緊張的。當晚,我花了很多時間重新檢查所有文件。我把之前模擬考口試的筆記全部拿出來再看一次,然後把 FAR 容易忘記的部分全部重新標在 iPad 裡面。重新檢查長途飛行的計畫(考試的時候,考官會給你一個預定的旅程,你要負責做出一份飛行計劃),再次檢查起飛降落的跑道長度需求,等等。然後立刻睡覺,因為考前一天實在是應該要好好睡飽。(講是這樣講,我那天還是因為很緊張沒睡好 XD)

考試的時候,這些東西務必記得帶:

  • 你的學生飛行執照、醫療體檢、記錄本(然後再次檢查所有 endorsements,尤其是 Solo XC 的部分都正確)
  • iPad 或是紙本的長途飛行計畫 (navlog, weight & balance, TO/LD distances)
  • FAR/AIM 書本(或是電子版)
  • 「所有的」飛機維修紀錄 (小提示:你拿到維修紀錄之後,記得先把所有需要的部分 (AAV1ATE) 都先上個書籤或是記錄下日期,這樣你考試當天就可以很快找到然後證明這台飛機可以安全飛行!)
  • 食物!考試當天會是你人生最長的一天,多帶一點零食或是食物保持體力!當天通常可能一大早或中午到,口試大概一兩個小時,飛行也要一兩個小時,你還要來回開飛機回去出發地(除非你剛好原場地考照XD),體力真的需要多保持一點。

我的考試中午開始,但我要從我的機場A出發去考官所在的機場B。我大概9:30am抵達我的機場,把飛機看了一圈之後去拿維修紀錄然後去俱樂部(我真的不知道這個中文該怎麼翻譯XDD)的會議室裡面檢查過所有的紀錄都沒問題,然後做個美勞把之前的 Solo XC endorsements 貼到飛行紀錄本裡面。十一點準時出發!這趟飛行沒什麼特別的,起飛之後就跟 NorCal 要了 Flight Following,然後一下就抵達了。

考試中午十二點準時開始,我們確認 endorsements 跟 8710 (IACRA) 的申請都沒問題之後,考官要我上 IACRA 簽名申請書,然後喝個飲料考試就開始了!他先解釋了整個流程,口試不會問刁鑽的問題而且會是情境題,然後完成的話,我們會先溝通飛行上機考試的流程然後就出發去飛一圈!

口試

口試一開始,考官就先設定了情境:我今天是第一次當 Pilot-in-Command 然後載他去 Fresno 玩。我要怎麼確定我可以合法載他?然後我要怎麼確定今天適合飛行?(PAVE, IMSAFE) 然後提到了飛行前檢查,他就問如果你的失速警報壞掉了,你該怎麼辦?我們可以飛嗎?如果發電機飛到一半壞了,我該怎麼辦?(最好的答案當然是,把你的信任的飛行檢查小卡拿出來,一步一步走XD)啊如果我今天飛到一半,我的乘客嘴唇突然變藍色怎麼辦?可能是什麼原因?我該怎麼辦?... 等等還有很多其他情境題。

中間也有問一些比較直接的問題,像是為什麼你轉彎的時候要踩方向舵?(Adverse Yaw) 氧氣什麼時候要用?10,000 MSL 以上有什麼法規差異?(雲的距離跟速度限制之類)喝酒之後多久才可以開飛機?飛機如果失速進入旋轉的話,要怎麼恢復?Special Flight Permits 的一些相關規定。

有一個問題滿有趣的:如果你飛到目的地了,但一路上有很多比預期強的逆風,然後 FAA 的人員突然過來跟你說要做 ramp check,然後說「欸,啊你怎麼只剩下 25 分鐘的油量,這樣不合法啊。」,你該怎麼辦?正確答案是「fuck off」(開玩笑,請不要真的跟 FAA 這樣說話XD)但問題是為什麼你可以不用鳥他?因為14 CFR § 91.151是這樣說的:”No person may begin a flight in an airplane under VFR conditions unless”。看到了嗎? “may begin a flight” 就表示你出發的時候有足夠的油量就可以了。(當然,請不要這樣做,你絕對不會想要在空中需要油的時候沒有油。)

這之間大概還有很多問題我已經忘光了XD 但最後一題我還記得。他問我說我覺得他有哪些 “hazardous attitudes” (FAA的手冊上有列出幾個標準的不良態度)。我跟他說我聽過其他跟你考過試的人講過,你好像全部都有喔 😂 我們笑了一下之後就再進入休息時間。

長途飛行計畫

休息完後,開始飛行之前我們要檢查一次今天的飛行計劃(實際上不會完整執行,因為考試還是有一些該考的東西,不是飛完一次長途飛行就好 XD)。考官首先問了幾個問題,為什麼我要選擇飛在 5500ft?(因為我們有經過一點山,這樣假設引擎失效,我們會有更多的滑翔距離同時目視飛行高度往東也是 Odd + 500ft)我怎麼計算起飛需要的跑道距離?如果今天是 30度C呢?如果氣壓設定是 29.92 呢?如果我們飛到一半迷路了怎辦?(有所謂的5C標準程序,不過這年頭又有GPS又有ATC各種東西可以輔助你,其實滿難迷路的。)

接著,考官問我有沒有帶紙本目視航圖。我說有,但是已經過期了,如果需要最新版的我 iPad 上有。他說沒關心,我們就用紙本的,因為比較容易攤開來指來指去然後討論。我前一天晚上也有在航圖上把今天的預定行程畫上去(就真的是拿一支麥克筆畫上去XD),所以我們就用了這條線開始討論這個地圖。

首先是一些空域問題:如果你看到一群 F-18 在前面的軍事作業空域(MOA)飛,你可以飛進去跟他們玩空戰嗎?(考官真的這樣問XD)我說「痾,我相當確定你要玩空戰的話,大概會超出 Cessna 172 的受力上限,但是,可以,你可以進入MOA只是要相當小心。」Class C 空域你需要什麼才能進去?你哪裡會需要使用 ADS-B out?你要怎麼查詢現在的天氣,但是不準使用 ADS-B In?(Flight Service!) VOR 是對準正北還是磁北?你要怎麼知道正北跟磁北差多少?

空域過後緊接著的是天氣問題。我來之前有先打給氣象服務台問過了,我說我可以先從這邊開始,然後再用 iPad 顯示完整的氣象資訊。我們先討論了我們經過的路上南邊會有一些亂流。他問我說你要怎麼知道,有哪些不同的氣象情報?(AIRMET Sierra, Tango, Zulu) 如果你遇到亂流,該怎麼辦?(減速到 Va, maneuvering speed)為什麼?(因為你的機翼會在達到受力極限前就會先失速)

另外一個有趣的問題在這邊出現了:如果雲的底層在 900ft 然後機場旁邊有紫色的陰影環繞,你法律上最高可以飛多高?然後你的高度計會顯示多少?

我開始一步一步來:雲是在 900ft 但是紫色陰影表示機場附近 700ft 以上就是 Class E,Class E 的雲距要求比較高,我不能飛太高近,但 Class G只要求不要進到雲,表示我最高可以飛到 700ft,但我就卡住了。到底為什麼高度計會顯示不同的數字?我卡了一下之後才想起來,啊,Class E 是在 700ft AGL (地面高度) 以上,但是高度計是顯示MSL (平均海拔)。所以我看了一下機場的高度,然後加上 700 就是高度計顯示的數字的正確答案。(這大概是在灣區學飛的問題 XDD 因為我很習慣高度計顯示的數字最後回到地面會回到 0 附近。我學飛的兩個機場 KSQL, KPAO 一個高度在 5ft 一個在 6ft 😅)最後我們又聊了幾個問題,像是 NOTAMs 怎麼看?如果溫度跟露點很接近,會發生什麼事情?

口試就到這邊結束了。我們稍微休息一下之後,然後我先去 preflight 飛機,就出發去上機考囉!

實機考試

考試首先就先來了一個 short-field takeoff,然後開始飛往第一個檢查點。考官要我不要使用 GPS,所以我就依據我的飛行計劃,爬升到預計高度然後就飛一個固定的 heading。(不過考官沒有fail我的iPad,所以我有稍微偷看一下確定航向正確,不過說真的,就真的你飛固定方向、固定時間,其實就是會到達那個點 XD 記得,計時器要打開,才知道你飛到了沒。)

當我跟考官說我看到第一個檢查點了(剛好是一個機場,所以在空中很容易看到),考官就叫我戴上一個遮住視線的帽子然後考一些儀器飛行跟從奇怪的飛行姿態恢復(這我也不知道中文該怎麼說,英文是 Unusual Attitude Recovery)。之後考了 Steep Turns(記得要飛 clearing turns,確保附近沒有其他飛機!),低速飛行(Slow Flights)跟失速和恢復,這部分都不難,然後考官就要我用 VOR 導航到機場 C,我出發前就大概猜應該會去這個機場,所以事先就先輸入了這個 VOR 的頻道,所以我就確認了一下頻道正確然後有顯示 VOR 代號後就直接把 CDI 切到 VOR,然後按 CRS 鍵直直前進。因為這個是一個有塔台的機場,所以我們要先聯絡,我就先打開自動駕駛後開始聽 ATIS 然後跟塔台要求進場。大概飛到一半後,考官就說好,可以用 GPS 了,我就按了 NRST,選擇了機場設定 Direct To 後,然後把 CDI 切回 NAV(不過 VOR 跟機場差不多位置,其實留著繼續用 VOR 也是無所謂),但用 GPS 好處是你也可以設定 OBS 到跑道方向,螢幕上就會有一條很大的線告訴你跑道在哪裡,這樣就很難錯過了。

但是這邊,就是我失敗的地方了 😭。第一個降落就是 short field landing,一開始都沒問題,但我可能那天太怕我超過了,反而導致我飛太低太慢,結果提早在 threshold 就觸地。我有嘗試要 go-around 但可惜太晚開始,我的輪胎還是碰到地面了。如果那天我稍微加一點 power,其實大概會勉強過關,但事後諸葛總是比較簡單...

考官告訴我說,那個不行要重考,但我們還是可以把剩下的考完,下次就不用重複考,所以我們又做了 soft-field landing / take-off。起飛後就直直飛出去離場,考官指定了一個高度跟航向,我就乖乖地照著手飛。(大概其實也可以用自動駕駛,但是這邊我猜大概要考我引擎失效了,所以我決定這段我就自己飛,一邊努力看隨時哪裡可以降落。)

大概在海岸線附近,考官就偷偷手伸過來把引擎拉到怠速跟我說,啊引擎壞掉了。這時候就要拿出 ABC, A = Airspeed (best glide), B = best field, C = checklist。所以我就調好速度,挑選降落點然後做一個標準的五邊進場然後開始跑一次 checklist (記得要說出你要 transponder 設定 7700,然後模擬一個無線電呼救)。我們從 2500 ft 開始下降,因為太高,我一開始就先放了 flaps 10 所以我們來得及下降跟轉 base / final (同時我也不想太低又飛到海上太遠)。我轉到 final 之後,考官就說這樣可以了,我們就保持在 1000ft 高度。接下來做了一個定圓飛行之後,就回到考官機場了。最後做了一個 forward-slip + no flaps 跟普通降落之後就回到機場。

暫時的失敗

考官跟我確認我們只需要重考 short-field landing,所以應該不會太難重約考試時間。但我實在被之前約考官的經驗嚇怕了,我當場就跟他約好下週四考試,他印了一張失敗通知單然後就結束了。

失敗歸失敗,我還是得自己把飛機飛回去。所以我花了一點時間坐在機場休息一下,跟幾個朋友分享失敗的消息之後就回家了。回程跟去程差不多都很無事,一樣是用 flight following 之後,大約下午四點回到我出發的機場。

在重考之前,我需要重新填一份 8710 / IACRA,重新訓練這個部分然後再要一個 61.49 endorsement,所以接下來一週我就跟我的教練約好時間練習重考。他也安慰我說,這沒關係,這很容易調整好,沒問題!

4/27 重考通過 🎉🎉🎉

我終於是有駕照的飛行員(畢竟不是把開飛機當飯吃,倒是不敢說是機師XD)啦!!!今天的飛行考試非常短。我大概早上 10:30am 飛到考官機場後順便先練習了兩三次短場降落。考官說他會稍微遲到,但我就先進去機場休息一下。他進來之後,跟上次一樣也是要簽名跟確認飛機 airworthiness 沒問題,我們就直接出發。

因為這次只需要做一個降落,我們就沒有離開這個機場。我做了一個簡單版的乘客說明後就起飛了。考官跟我說「你可以選擇要不要做一個練習降落。你只要降落前跟我說就好。」我想了一下,我想說反正早上我來的時候也練習過了,就直接上吧,長痛不如短痛!「就直接來吧!」我話剛說完,馬上就聽到兩台飛機想要加入這個機場的 pattern,搞得我要飛一個超~~~~長的 downwind,整個打破我的計畫。我們就保持在 TPA ,但我放了 flaps 10 先減速,免得跟前面飛機太近。直到轉 final 的時候才開始真正減速跟調整飛機。不過也因為很長的 final,實際上沒有遇到問題,我很順利的把飛機壓在 short final 的時候飛 59kts,瞄準在跑道頭然後留下一點點 power 讓我們可以 hover 到跑道數字,那時候才把 power 完全拿掉,飛機也乖乖的降落碰到地面。隨著我開始煞車跟放掉 flaps,考官跟我說「恭喜!你通過了!」。我真的是心中超開心,但當然我還在開飛機,得先停好再來歡呼也不遲 XD 停好飛機後,我們就去他的辦公室把新的臨時飛行證書印出來,我就正式持有一個自用駕駛執照 (Private Pilot) 啦!

P.S. 機場B真的是一個非常忙碌的無塔台機場。前陣子還有發生過有人要 straight-in 跑道然後跟其他飛機空中相撞死人的事件。我離場的時候就聽到有一台飛機再說他們要 straight-in,無線電上其他人馬上說「哎天啊,又有一場悲劇要發生了」還好這次安全沒事,他們最後也選擇 45 entry traffic pattern。我一邊聽一邊看著 ADS-B 的飛機位置地圖真的是替他們捏比冷汗。大家在外飛行還是要小心啊!

CCS, the Combined Charging Standard, is THE standard in the EV charging. There are two plugs you can find out in the wild, respectively called CCS1 and CCS2. The actual DC plug looks exactly the same, the only difference is being the top AC port where CCS1 uses the US standard and CCS2 uses the EU style plug.

The two primary plug differs in carrying single phase / three phases of power, in the US where single phase is prevalent, we use the CCS1 plug. In the EU where three phases charging is ubiquitous, the CCS2 plug is used. Due to the difference being mostly with how the electrical grid works, most country will use a single plug throughout their country.

We would not be writing an article today if that's the case everywhere, would we? 😂 There is one country in the world where you can actually find both CCS1/CCS2 everywhere in the country, and that country is Taiwan. (If there're more oddities out there, let me know!)

Tesla NA, CCS2 plug from the same supercharger ▲Tesla CCS2 cable plugged into the car and the NA plug from the same supercharger is shown

Before 2021/7, all the Tesla in Taiwan uses the Tesla NA plug (Tesla's small proprietary plug). This is the same plug used in Teslas in the US because Taiwan's power grid is very similar to the US's. However, the Taiwanese government announced intention to standardize EV plugs into open standards. Not sure what exactly went wrong with the negotiation with Tesla here, but instead of going with CCS1 (like in South Korea where the CCS adapter is on sale). Tesla announces that they'll switch to CCS2 instead in Taiwan, probably because the parts are readily available for the EU market already. (Not sure if two coincides, but currently Tesla sends cars from their Germany factory to Taiwan as well.)

CCS1 and CCS2 stations side-by-side

This creates an interesting situation. You can actually see cars and charging stations in Taiwan with both CCS1/2 plugs. Non-Tesla cars are still mostly using CCS1 standards in Taiwan, while third-party charging stations are rushing to add CCS2 ports and stations as well.

Tesla Supercharger with plug signs

Is it a good thing or a bad thing? Honestly, as a user, I love being able to access ALL charging stations. I rented a CCS2 Model 3 in Taiwan and I have access to all kinds of third-party charging stations (one-time even had three-phase AC charging in a random farmer's market in Hualien!) I really don't mind the bulkier connector, because honestly, how many times are you plugging that plug in/out anyway? The only downside is that sometimes I need to verify if the station has Tesla/CCS1 or CCS2 plug before backing in. While I wish Tesla went with CCS1 plug in Taiwan, it turned out better than I expected, so I guess all in all, it is indeed a good thing, and an interesting oddity in a small corner of the world.

Charging in an old gas station island ▲Bonus pic: There's a gas station in highway rest area converted an island into EV charging stations.

Using Diesel with Rocket usually require the use of rocket_sync_db_pools crate which hides the complicated setup of initializing a DB connection pool and expose it to handlers via a opaque type that you can call run on to get a Future back and only in that Future you will get a connection.

This makes writing a integration test with a Rocket handler a bit more complicated because the impl of the DB Pool guard type is generated on-the-fly and not bind to a trait, so we can't just write a mock implementation of it.

After some trial and error, I realized that you can initialize Rocket to the Ignite state (initialized but not launched/listening yet). We generate a new test DB on-the-fly for every test so we also need to config the Rocket instance to use the right test-specific DB url. Here's the code doing so:

pub async fn rocket_test<F, Fut, R>(&self, f: F) -> anyhow::Result<R>
where
  F: FnOnce(DbConnection) -> Fut,
  Fut: Future<Output = R> + Send + 'static,
  R: Send + 'static,
{
  let figment = rocket::Config::figment()
    .merge(("databases.db.url", self.db_url.clone()));
  let rocket = rocket::custom(figment)
    .attach(DbConnection::fairing())
    .ignite()
    .await?;
  let conn = DbConnection::get_one(&rocket)
    .await
    .ok_or(MyError::DbError(
      "unable to get db connection".to_string(),
    ))?;

  let result = f(conn).await;

  rocket.shutdown().notify();

  Ok(result)
}

and therefore, you can write tests as such:

rocket_test(async move |conn| {
  let ret = a_rocket_handler(
    conn,
    params,
  )
  .await
  .expect_err("handler should fail");

  assert_eq!(
    ret,
    MyError::BadInputError("fail".to_string()),
  );
})
.await
.unwrap();

This is an article about my experience learning how to fly an airplane. Given it's rare in Taiwan to have a chance to learn general aviation, I'm gonna write this article in Traditional Chinese instead, an English version might come later.

上面那些都講完之後,就可以談談實際的飛行訓練了。這篇來聊一下學校的差別跟訓練的各種階段。

學校的種類

前面提到,我找的學校其實是一個俱樂部,你要自己找老師然後租用俱樂部的飛機來飛。這樣的學校通常被稱為是 Part 61。另外有一種比較職業導向,目的通常是訓練職業飛行員的學校被稱為 Part 141,這些學校通常有比較嚴格的課程規劃、對學生的要求也比較高、你也需要有更多的時間跟精力上的 commitment,一些著名的代表包括長榮在 Sacramento 的 EVA Flight Training Academy

這篇因為是在講我個人的經驗,提到的都是 Part 61 的狀況,但 Part 61 很看老師的教學風格,所以你如果去學也有可能遇到一些不同的情況。

地面訓練 (Private Pilot Knowledge Exam)

這個部分主要是在幫你準備筆試的部分,實際上的內容包羅萬象,從機場的號誌標線到航線的規劃與天氣應變,通通都會出現在考試題目上。

實際上的考試是去考試中心,有兩個半小時的時間(但大概半小時到一小時可以做完)。你可以攜帶一個航空計算機 (E6B or 電子版的計算機,但不可以是手機 app)進去以及圓規跟量角器。後者通常用在 Cross-Country Flight Planning 上會要你看航圖然後計算角度、距離以及時間等等的題目。考試的內容由於是當場隨機決定(有一個範圍),我其實考試當天沒有用到圓規跟量角器。

如何準備?我想台灣長大的各位應該都很會 😂 背考古題!我滿推薦 Sporty's 的課程,他有實際的影片可以看、也有各大平台的網站、app可用讓你練習考古題。考前就一直狂做這個,考試當天就沒問題了!練習的時候,我建議去買一本或是印一本 Private Pilot Test Supplement,因為剛剛講那些需要航圖的題目很需要用紙筆跟工具量測。

這個階段跟飛行訓練可以並行,但我建議開飛之前至少先看過一輪內容,了解基本飛行常識。但實際考試可以拖到 checkride 以前都可以。我自己是在 Solo XC 之後才開始考試。考試前需要老師的許可(或是你用 Sporty's 也可以取得線上許可)才能考試。Checkride 有機會 DPE 會問你筆試上答錯的題目(成績單上會印出錯誤的題目類別代碼),所以記得準備好再去考試。我自己很幸運的,雖然有幾題不是很確定,但拿到了 98 分!😁

第一階段訓練 (to Solo)

一開始最重要的訓練大概就是跑去附近的練習空域,然後一直在上面做各種飛行練習 (maneuvers)。在灣區,附近常用的練習空域就是在 Half Moon Bay 上空以及 Stanford 以北到 Crystal Springs Reservoir 一帶。

SF Bay Area Practice Area

到底在做什麼練習呢?一開始的時候當然就是一些基本的飛行控制,知道如何爬升、下降、轉彎,然後綜合起來,爬升轉彎、下降轉彎等等。這些基本操作都沒問題了之後,就會開始練習 Stall (aka 雲霄飛車,ㄜ 不是,失速)。

題外話:引擎熄火也叫 Stall,像是車子或重機上坡起步那個,所以我剛開始的時候也想說,引擎跑得好好的,幹嘛突然熄火 XD 後來才知道,Aerodynamic Stalls 是指飛機機翼無法產生足夠升力的狀況。

人活得好好的,為什麼要讓飛機失速?」我想很多人心中大概會冒出這個問題,對,我也是這樣想的。飛機其實在降落的時候,我們並不是直接讓飛機想辦法盡快接觸地面,這樣的結果輕則重落地(就是你搭客機的時候,有時候降落完會想問候機長的那種感覺(誤 ),重則有可能因為落地的壓力太大導致輪子折斷、爆胎等等。

飛機要降落其實是在靠近地面進入地面效應 (Ground Effect) 的時候,此時飛機的氣流被地面擾亂反而減少阻力進而提升飛機性能,在這個階段,我們會輕輕的把機頭往上拉,讓他慢慢減速但又不爬升,最後失速停止飛行而落在地上。這個階段如果你做得很細膩,就可以降落的很舒服很平緩。但實際上,會因為各種風向、進場穩定度等因素,尤其對新手來說,很多東西要控制得宜才能成功降落。

離題了,回到 Stall 練習。這個練習的目的就是教你如何把飛機進入降落的狀態,如果需要 go-around 要怎麼正確的復飛等等。最後也會教你 Traffic Pattern,中文常稱為五邊飛行。飛機進入機場通常會飛一個固定的路線,把不同跑道的飛機隔開,同時也方便讓駕駛容易掌握狀況、調整飛機。這個固定的路線就是 Traffic Pattern。以 KSQL 為例,通常我們會利用 30 跑道,這個跑道是 Right Traffic,也就是所有彎都右轉。從寫著 12 的那頭起飛後 (Upwind),右轉進入 Crosswind,隨後右轉進入 Downwind,最後右轉 Base 以及 Final,再次降落在 30 跑道上,這個就是一個 Pattern Work。

KSQL Runway 30 Traffic Pattern

當你可以成功自己降落飛機的時候,還沒完呢!還要教你會處理緊急情況,尤其是飛單引擎飛機失去引擎的時候怎麼辦?當然,飛機之所以叫飛機就是因為他很會飛,即便失去了推力也不會導致飛機瞬間墜毀。但失去了推力你就得盡快嘗試重啟引擎、如果失敗得關閉引擎,調整飛機姿態取得最大滑翔距離,隨後與空管連絡請求協助並挑選適合的降落場地(可能是附近的平地但也別忘記,如果可以滑翔到機場,機場當然是個最好的選擇)。

灣區公共的商用機場其實都可以讓小飛機降落使用。像是 Oakland (KOAK), San Jose (KSJC) 都可以讓小飛機降落跟練習使用。有時候在大飛機之後進場,很有突兀感 😂 (但也要小心前面的 Wake Trubulence,小飛機很容易被大飛機之後的氣流擾亂,所以這個情況,我們要比大飛機的進場路徑高然後要降落在比他們降落的點前面一些以避開氣流。)

SFO 理論上也可以讓你降落,但降落與處理費可能會收你個幾百塊美金 😅

上面這一大堆都學會了之後,最後就會進行一個 Solo Phase Check,這時候會請另外一個教練來跟你飛,確認你有獨立安全飛行的能力。之後就可以自己在很多限制之下短程飛行。而且緊接著進入下一階段的訓練!

第二階段訓練 (to Solo XC)

以我的狀況,教練在我 Solo Phase Check 通過之後並沒有讓我馬上 Solo,而是乾脆直接進入 Solo Cross-Country 的訓練。所謂的 Cross-Country 並不是真的要你自己從東岸飛到西岸(在美國飛小 Cessna 172 應該會飛到吐血 😂),而是指飛行兩個機場有 50nm 以上的直線距離。因為距離變長了,考驗的項目就變成了航線的規劃(怎麼決定你要飛多高?要怎麼知道障礙物多高?飛多低是安全且合法的?氣象怎麼查、怎麼決定避開還是晚飛?目的地機場附近怎麼辨識?跑道在哪邊? Pattern 方向/高度?... etc.)以及你跟空管員/在無管制的小機場(Uncontrolled Airport)跟其他飛行員溝通的能力。上一篇有提到一個可以買的軟體是波音的 ForeFlight,這時候就展現出他的好用之處了,上面提到的東西幾乎都可以在上面查到,你也可以用他規劃飛行計劃甚至實際飛行時,搭配 ADS-B receiver 直接顯示附近的飛機在哪邊以及提供語音提醒。

在跟教練飛過幾個遠的機場後,也跟上面一樣會進行一個 Solo XC Phase Check,在這之後就可以自己飛行長途的機場了。這個階段因為你還沒有駕照,每次長途飛行都會需要教練簽核你的計畫。也有可能遇到很多次因為天氣必須推遲飛行的狀態(像是灣區秋季很容易早上會起大霧要等到中午左右才會消退到足夠可以目視飛行)。

Snapshot of the GA airports I've visited in 2022

在這個階段超級好玩!因為你可以開始到處亂飛(也必須要飛一些比較長的飛行才能滿足考照要求與時數要求),上圖是我最近去過的機場,藍色的是出發地,橘色的是 Touch-and-Go 或是 Taxi-back (通常是在第一階段跟教練去過的),綠色的則大多是我自己去,有短暫 (讀作 “進去上個廁所”) 進去 FBO 的機場。我有一次甚至飛去 Sacramento Mather Airport,順便去附近台灣超市買個貢丸回家 😁

FBO: Fixed Base Operator

其實就是在機場上面提供飛機服務的地方,通常有地方讓飛行員可以短暫休息也可以幫飛機加油。雖然別人都是搭私人專機,你是開自己的小飛機,很有格格不入感 😂

最後準備考試 (to Checkride)

這部分就留待下集待續啦!因為我也還沒正式進入這階段,預計是 12 月開始練習準備最後的口試跟實機飛行考試,希望可以順利拿到駕照!

This is an article about my experience learning how to fly an airplane. Given it's rare in Taiwan to have a chacne to learn general aviation, I'm gonna write this article in Traditional Chinese instead, an English version might come later.

說來想學開飛機的想法也已經存在很久了,但都一直沒有付諸實現。要開始學飛雖然不然,但也很多雜七雜八的事情要思考跟計畫,所以就一直拖拖拖到現在才終於正式開始。這篇先來聊聊正式開始學飛之前會遇到的東西。

開始

怎麼會想來學開飛機?大概是COVID之後有點無聊吧XD 但最早第一次在 Georgia Tech 聽到同學有學過開飛機之後,就驚覺「咦?原來這是一個大家都可以學的東西嗎?!」。後來畢業隨著工作搬來了灣區,也遇過朋友開飛機帶我去 Bay Tour (繞一圈灣區,會經過幾個著名的景點像是金門大橋等等),那天也很幸運航管員(ATC, Air Traffic Controller),願意讓我們直接切西瓜經過 SFO 上面那個又複雜又大的 Class B airspace,難得拍了一張從空中拍SFO的照片。也遇過同事開飛機載我跟同事去 Tahoe 滑學,那種可以跳過塞車的感覺實在好爽,就隨著這些東西慢慢累積起了一點想真的去學的念頭。

從空中看 SFO

學飛(假設是PPL, Private Pilot License),基本上可以分成兩個部份:地面知識跟飛行時數。所以也有聽過有人建議,不然乾脆先自己學地面知識,網路上確實也有很多免費的資源可以學,但沒有實際飛行的「需求」實在有點難持之以恆。我嘗試在公司開了 #learn-how-to-fly 的 Slack channel,想說找幾個同事一起學,但最後沒有成功。XD 不知道為什麼,去年後期加入的同事有好幾個有PPL執照,頻道開始比較熱絡一點,給了我比較多動力開始學。剛好也有一個同事就在我的team上,我們一起開飛機去了Watsonville,回程途中他讓我飛了一小段,就感覺:「好吧,就是這次了。就認真去學吧!」

真的想學了,接下來就是找地方了。滿多未來想當航空公司機師的人,通常會去找飛行學校,但我沒有這個興趣也沒有這個時間能這樣用,所以必須找一個能跟我時間搭配的教練一起,也沒有自己的飛機所以也需要找地方租飛機。問了一圈,好像滿多我認識的人都是加入 West Valley Flying Club 這個飛行俱樂部。加上之前提到加入我的team的同事,也剛加入,需要找人給一個 checkride 確認飛行技術才能開始租飛機。我們那天出去飛一圈回來的時候,剛好就遇到他找的 CFI (Certified Flight Instructor) 準備帶學生出去,我就要了一下電話,之後就決定就乾脆找他直接開始吧。 XD 一個非常隨性又隨便的流程。(其中一部份原因也是這個 club 同時有 KSQL (San Carlos) 跟 KPAO (Palo Alto) 兩個地點,對我來說比較方便。辦公室裡面還有養一隻可愛的黑貓。

流程與文件

地點與時間

學飛真的是一個需要「時間」的事情,因為很多東西都需要實際操作才能體會,所以就必須要一直飛飛飛飛飛。但白天又要上班,就真的需要安排一下。建議最少一個星期能抽出兩次,最好三次的時間。每一次大概會需要三個小時(實際飛行時數大概會落在 1.8 小時上下),前後有一些飛行前檢查跟停妥飛機跟填寫紀錄本的事情要做會花掉一點時間。我最後跟我老闆僑好讓我平日下午一天提早下班去飛然後回來之後多上線幾小時補回來,另外一天就找週末去,還好我在灣區天氣晴,不太會有需要取消的狀況。有時後會需要在地面上課,補一下知識,這個如果你的 CFI 情況許可,就可以直接排在晚上下班後,比較好安排。

地點跟時間另外一個影響的就是飛機,前面提到 WVFC 同時有 KSQL, KPAO 兩個地方,所以稍微比較有彈性一點但偶爾也會遇到新飛機沒有了或是某個地點飛機都固定時段租光了之類的也要注意一下。

錢錢

對,不可否認學飛還是一個滿貴的事情。雖然說在矽谷當工程師收入不差了,學飛的支出還是會讓人多想一下。最基本的就是需要飛機跟教練,灣區這邊飛機,比較新的玻璃儀表飛機 (Cessna 172 G1000) 大概要 $180 ~ $220/hr 上下,教練從 $80 ~ $140/hr 都有。一次上課通常會收到 2.5hrs (飛機算實際飛行時數,大概是2小時)。加一加,上一次課就需要就 $650 上下了,一週需要兩三次。

除此之外還有一些額外要買的東西:

  • Bose A20:嚴格來說也不是必要,但抗噪耳機真的很讚。平常搭飛機也都會想用抗噪耳機了,飛行的時候你離引擎更近還需要跟 ATC 講話,有個好耳機真的還是幫助很大!($1,095.–)
  • Foreflight:超級好用的各種航空資訊 app,從飛機 Traffic 資訊(需要另外連接 ADS-B 接收器或是至少飛低一點的時候有網路)還有各種航空圖跟機場圖。一樣也不是必要,但非常好用!Foreflight 建議使用 iPad Mini Cellular 來跑,mini 大小比較適合而 Celluar 版本有 GPS 緊急情況可以當備用導航使用。 ($199/yr,加入 SAFE 有額外額扣) 不想花錢的話,可以用 SkyVector 但就沒有離線(除非你印出來XD)。
  • 筆記本、筆跟 Checklist:一些小東西,也沒多少錢但就在聊錢了就拿出來講一下。Checklist 跟飛機機型有關,學飛很常用 Cessna 172S / G1000。

外國(星)人的特殊步驟

因為美國文件都稱呼外國人是 Alien,因此以下我們都用外星人稱呼自己 XD 外星人想在美國學飛要先做一個背景調查叫 Flight Training Security Program (以前叫 Alien Flight Student Program XD),其實就是需要多一個指紋的步驟。大概一兩週就會下來很快,在這之前的時數無法紀錄在 logbook 上面算入正式訓練時間。

(題外話,一路上從簽證、綠卡跟 Global Entry,美國也不知道調查過幾次我的身家了,這種東西可以 share 一下嗎?我很樂意簽個資訊分享同意書 XD)

體檢

體檢倒是意外的麻煩。FAA 雖然有個官方網站可以查 AME (Aviation Medical Examiner),但你只能輸入一個地點然後之後還要一個一個打電話約約看時間,交叉看一下 reddit 上大家的經驗,總之是個有點花時間的步驟。PPL 一般來說只需要持有三級體檢 Third-class Medical Certificate,基本上沒有太多奇怪的問題都可以開飛機。

這個步驟建議提早開始做,免得最後體檢過不了,學飛的錢就浪費掉了。不過到你單飛 (Solo)之前都不需要體檢結果,所以你可以評估一下什麼時候要做。

特殊頒發 Special Issuance

有些醫療情況會導致你無法立刻通過三級體檢,需要再送文件給 FAA 額外審查之後才能拿到 Special Issuance。如果你有這個需求,我建議跟 AME 問一下 FAA 大概會需要哪些文件,先跟你的主治醫生弄好證明後直接就寄過去 FAA,同時建議每週打個電話過去問一下進度。我不知道會不會真的比較快審核你的申請,但總之兩三個月過後,我也還是拿到了。比較討厭的是,我的 SI 只有一年有效,之後可能要提早重新申請或是乾脆就改用 BasicMed。

到這邊如果你都做了,你應該已經開始在上課了。下一篇再來聊聊我自己上課的心得!

I am a lazy person so I've been really just compiling the code I want to run on Raspberry Pi ... well, on Raspberry Pi. It was slow but it is super simple to setup. However, sometimes you just want to compile something larger than the Raspberry Pi can handle. What now?

The first thing my lazy butt tried is to simply run a ARMv7 image using qemu-system-arm but that sadly is very slow on my computer due to emulating a different architecture altogether. I was also too lazy to setup a proper buildroot with all the toolchains and libraries properly cross-compiled for the ARMv7 architecture.

I decided to give another approach a try: using qemu user-mode emulation to run ARMv7 userspace directly and to wrap it in docker so I don't need to worry about messing my system up. We should be able to get near full-speed with this method.

Fortunately, someone already published an ARMv7 docker image agners/archlinuxarm-arm32v7. We just need to get our system to run ARMv7 file now. To do this, we need to install binfmt-qemu-static from AUR. This enables your system to run ELF files from other architecture.

If you just start running the container at this point on, you will run into this weird problem:

[root@f19789b92d0d code]# cargo build
    Updating crates.io index
warning: spurious network error (2 tries remaining): could not read directory '/root/.cargo/registry/index/github.com-1285ae84e5963aae/.git//refs': Value too large for defined data type; class=Os (2)
warning: spurious network error (1 tries remaining): could not read directory '/root/.cargo/registry/index/github.com-1285ae84e5963aae/.git//refs': Value too large for defined data type; class=Os (2)

Value too large... for wat? I didn't read into what exactly caused this but someone hypothysize that it could be filesystem compatibility between 32-bit/64-bit (ARMv7 is 32-bit and my PC is 64-bit. If you run the ARM64v8 image than it should just work) systems so we need to mount a filesystem that works on a 32-bit system. I've tried using mkfs.ext4 -O^64bit and even mkfs.ext3 but they all still produce the same problem. I decided to try another filesystem altoghter and JFS works!

To create a JFS image, you can run:

fallocate -l 4G disk.img
sudo mkfs.jfs disk.img

and than you can run this to mount it:

mkdir mnt
mount -o loop disk.img mnt

That's it! Once you have that JFS filesystem setup, you can run this command to run ARMv7 Arch Linux in docker and compile whatever you need!

docker run -it --rm -v $PWD/mnt:/work agners/archlinuxarm-arm32v7

The #BlackLivesMatter is happening in the US. It feels like a very very distant event for Taiwanese and yet it is happening right beside me. I've seen a lot of viewpoints from the Asian American community and that got me thinking: What am I feeling and thinking as a Taiwanese expatriate living in the US.

[The English version was translated and expanded on my original text, in Traditional Chinese.]

To be honest, I know next to nothing about racism when I came to the US years ago. I grew up in Taiwan all the way until I finished my master's degree. I haven't been hearing a lot of racism being talked about in Taiwan (not that Taiwan does not have it) and that I didn't have a deep understanding of the US history, and quiet frankly, I still don't today. It could be that I'm lucky or insensitive to it, but I also never deeply felt that I was being discriminated because of my racial background. The biggest discrimination I felt since I left Taiwan is the oppression on my country. Almost no one recognize Taiwan as a country and we need to somehow navigate these gaps as a Taiwanese individuals. #YourCountryIsNotACountry I can totally understand that some Taiwanese people, living 7500 miles away from the US, probably don't have the context to build empathy towards what is going on here.

As I'm staying longer in the US, I get to know more people of different backgrounds. I hear more things about my friends, about what's happening around me. And as I was rebuilding my identity now that I don't live in my own identity bubble, I've read on more things. It's really hard to not start to feel and think more deeply about racism. It has become a problem I might have encountered myself rather than some distant story. I've read on an article today “Black Lives Matter, Taiwan’s ‘228 Incident,’ and the Transnational Struggle For Liberation” that really resonate with me deeply. Growing up in a country that is being alienated by the international community, I have never though about one day we will be drawing parallels from the 228 White Terror that happened in the dictatorship-era of Taiwan to the Black history and current events.

Taiwan has came a long way since the dictatorship era. We grew to be one of the modern democratic and progressive country in Asia. This did not happen without protests, so we should know very well ourselves. More recently, we had the Sunflower movement in 2014, we have many same-sex marriage protests throughout our history until we finally legalize it in 2019. We really should know what is going on. The Taiwanese society cares a lot about being “polite”. Our movements put a lot of emphasize on projecting that image. Everyone is very conscious about it. We would be fighting our way into the legislative yuan while self-patrolling to make sure no one is hurt, no cultural artifacts in the building was damaged and protesters clean everything up afterwards. Yes, those are all great, but is that really everything? We've felt deeply when Hong Konger was protesting for their freedom and saw the police brutality over there as well. It all got me to think about what exactly is a protest and where do I draw the line? In the face of the oppression and systematic discrimination that the black community having going through, these doesn't matter. Minnesota officials also found that arrested looters are linked to the white supremacists groups. We have seen this too. There were gangsters trying to blend into our movements and try to incite violence and escalate too. We should understand what is going on. We've always felt that we were being discriminated on the international community and we should have the empathy here too as it is far more personal than ours.

I'm really glad that we have Taiwan. I may have not been living in Taiwan but seeing us gaining more momentum and visibility on the international stage really makes me happy. A few recent big policies are heading towards the progressive path. I felt really lucky and proud that I'm Taiwanese, but we are also far from perfect. We have not finished our own transitional justice for the 228 incident and we have our own racism problem towards migrant workers from the SEA countries too, not too mention casual racism that I still hear occasionally. I'm not saying every single Taiwanese person should care about all the things in the world, and that is perhaps not necessary. However, the very very least we can do, is to look at what is happening, and at the very least, trying to prevent it from happening in Taiwan too. And if you do live in the US, we should care. It's unjust and we are not protected from racism at all.

中文版

最近幾天我想大家應該都知道,美國正在大規模的抗議 #BlackLivesMatter 的事情;是一個感覺離台灣人很遠,但卻正在我身邊發生的事情。

身為一個住在美國的台灣人,剛來美國的時候,說真的我對種族歧視的認識剛開始真的沒有很深。一方面在台灣這是比較少被提到的問題(並不是台灣就沒有這個問題),一方面我對美國的歷史脈絡認識的也不多。即便如此,黑人也好、亞洲人也好被歧視的事情依然時有所聞。也或許是我神經大條吧,我自己沒有深刻的感受過因為我的種族背景而被歧視過,一直以來我出國之後感受到最大的打壓大概是我自己的國家吧。 #你的國家不是國家 因此,我完全可以理解在台灣出生、長大的人,大概很難對這件事情有很深刻的體會。

但時間久了,認識的人變多了,聽到的事情變多了。隨著出國之後重新建立自己認同的過程,看的東西也多了。真的很難不對這些事情開始有感覺,會去思考。畢竟種族歧視對於一個住在國外的我來說,是個很切身相關的問題。而今天,看到了一篇文章真的有點打到我,”Black Lives Matter, Taiwan’s ‘228 Incident,’ and the Transnational Struggle For Liberation” 這篇文章在講 228 白色恐怖跟現在 #黑人生命無價 的運動有什麼相似的地方。我從來沒有想過台灣的歷史跟美國與黑人的歷史能夠連結在一起,能夠有共鳴。有興趣的人建議讀讀。

難得說了這麼多話,我想說說我自己看到什麼:先說事情本身吧,一個手無寸鐵的黑人被壓制在地上,被警察用膝蓋壓著脖子不能呼吸長達好幾分鐘,中間一直求饒、求助說自己不能呼吸。然後,最後真的就這樣被壓死了。我想大部分的人都無法認同警察的作為。加上美國長期社會、警察對於黑人的不公平、暴力,民眾群起抗議,我想有在關心美國新聞的人應該不難想像這件抗議的產生,#BlackLivesMatter 運動今天也不是第一天。確實,看到有些抗議活動被暴力圍繞,有人砸店等等。但是,在我身邊 Bay Area 附近,也多得是很多城市抗議什麼大事也沒發生。甚至隔天也有志工在街上清理。而我同樣身為非主流群體的一員,雖然無法說是受到相同的迫害,真的可以理解為什麼會這麼生氣,也很支持這個抗議。

台灣這幾年的抗議運動、香港去年持續之今的反送中,都讓我重新思考到底抗議活動到什麼程度是合理的。在台灣,或許大家認知到我們自己的社會多在乎「要有禮貌」,大家非常非常注重抗議的形象。一邊衝進立法院,一邊還要自己組織糾察隊保護大家安全,自己整理好環境。這些都是非常好的事情沒錯,但我也可以體會在抗議的氣頭上,這些事情或許相對不是這麼重要。砸無關的店家,趁火打劫,這些我還是無法認同,但實際上,這些人是不是真的是抗議份子還很難說,Minnesota 官員也說抓到的打劫犯跟白人種族主義團體有關。這不是跟台灣大家在抗議的時候,很怕很小心自己被跟黑道份子連結一樣嗎?我們應該要更能夠拿自己的經驗將心比心才是,也應該要能夠用自己在國際上被長期歧視的心情感受。

想想,我們真的很幸運有台灣。這幾年雖然不在台灣,但看到台灣在國際上的能見度越來越高。幾個重大的國家政策也往進步價值的方向前進,說真的,我覺得我自己很幸運也很驕傲是台灣人。但台灣也不是完美的,說回228我們自己的轉型正義也還沒完成,而到現在也一直還是有歧視外籍勞工的現象。(最近不也才剛發生北車事件?)或許說要每個台灣人都關注世界大事是有點難,也沒有必要。不過我覺得至少,或許我們可以看看別人發生過什麼事情,避免台灣在未來也發生一樣的事情。

I want to talk about one problem that has been bugging me as a motorcyclist for a while. I usually ride with a helmet cam with me. For example, I've been to Japan for some motorcycle road trips before. I've collected hours and hours of videos of the roads ahead and some other different angles. However, it is really hard to find a highlight in the video.

Sometimes you noticed something interesting going on the road. Taking one example from my recent trip to Napa, I saw two squirrels fighting on the road as I rode by. (okay, it is both interesting and scary at the same time, luckily I managed to miss them.) How do I recover these highlights from a boring long video? The problem is that roads looks very similar and it is very easy to miss the exact moment you see something when you are skimming through the video.

I first thought about GPS might work if I can just remember where it happens and it turns out it's really hard to remember at which corner you see fun stuff and even if you do, synchronizing the video with recorded GPS tracks is usually a long process even if your helmet cam records GPS track at the same time as well. I thought about making a hardware button that just records a timestamp but then I will first need to figure out the right hardware to make one then to mount it on the bike and to synchronize it with the video too.

Finally I had a really simple idea. What if I just use my hand to cover the camera? It's simple, easy to do and now all I need to figure out is how to detect black frames from the video.

Here is one of the example of how a “marker” would look like on video when you use your hand to just cover the camera for a second. As long as you are covering the lens, it should produce a very dark frame comparing to regular day time riding videos.

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, dist = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY)
dark_pixels = np.count_nonzero(dist == 0)
dark_percent = (float(dark_pixels) / size * 100)

We first convert the frame to grayscale for easier processing since all we card are detecting black pixels anyway. Then we run the frame through a threshold filter to mark anything below gray level 30 to 0 (perfect black) and anything else to 255 (perfect white) then we count the pixels having value equals to zero.

A grayscale threshold-processed frame

Now we take this snippet and apply a bit more logic: let's say we will count a frame as a marker if more than 95% of its pixels are black. We might also have multiple marker frames when your hand is moving in and out of the view so we will want to merge close-by marker points, let's say we will only have 1 marker per 5 seconds. Now we can write out the final code!

import sys

import math
from datetime import datetime
import numpy as np
import cv2

MERGE_THRESHOLD_MS = 5000


def format_time(timestamp):
    msec = timestamp % 1000
    parts = [msec]

    secs = math.floor(timestamp / 1000)
    parts.append(secs % 60)

    mins = math.floor(secs / 60)
    parts.append(mins % 60)

    hrs = math.floor(mins / 60)
    parts.append(hrs)

    parts.reverse()
    return "%02d:%02d:%02d.%03d" % tuple(parts)


def main():
    src = cv2.VideoCapture(sys.argv[1])
    if not src.isOpened():
        print("Error opening file")
        sys.exit(0)
    length = int(src.get(cv2.CAP_PROP_FRAME_COUNT))
    width = src.get(cv2.CAP_PROP_FRAME_WIDTH)
    height = src.get(cv2.CAP_PROP_FRAME_HEIGHT)
    size = width * height
    markers = []
    start_time = datetime.now()

    while src.isOpened():
        ret, frame = src.read()
        if not ret:
            break
        idx = int(src.get(cv2.CAP_PROP_POS_FRAMES))
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        _, dist = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY)
        dark_pixels = np.count_nonzero(dist == 0)
        dark_percent = (float(dark_pixels) / size * 100)
        frame_time = int(src.get(cv2.CAP_PROP_POS_MSEC))
        fps = idx / (datetime.now() - start_time).total_seconds()
        print("\033[0KFrame %d/%d [%s]: %.2f fps, %.2f%% black. %d black frames found.\r" %
              (idx, length, format_time(frame_time), fps, dark_percent, len(markers)),
              end='')
        if dark_percent > 95:
            markers.append(frame_time)

    merged_markers = []
    for marker in markers:
        if not merged_markers or marker - merged_markers[-1] > MERGE_THRESHOLD_MS:
            merged_markers.append(marker)

    print()
    print("Markers:")
    for marker in merged_markers:
        print("  %s" % format_time(marker))

    src.release()


main()

To actually run this script, you will need to have opencv-python and numpy installed.

One thing I have not figured out on how to improve is the performance of the script. It currently takes about 5 mins to process this 26 mins long video. It looks like most of the processing is done on CPU (decoding/analyzing). I'm wondering if try to move some processing into GPU would help with the speed but that's another topic for another time!

And this is the story of how I recover that squirrel snippet from a 4 hours long recording!