pretty code

2022年8月21日 星期日

Install PCL on Windows 10

PCL 是一個點雲運用的函式庫。

官方在 Download 頁面中建議使用 vcpkg 來安裝,在過程中有遇到一些問題,記錄一下以免忘記。

建議用 Linux 應該會比較省事或者是使用 PCL 官方預先編譯好的版本(github),但就必須安裝一樣版本的開發環境,目前 1.12.1 版配合的是 VC2019。

01. 安裝 Visual Studio Build Tools 2017

此刻 PCL 的版本是 1.12.1,我電腦的環境是 VC2015,因為 PCL 是用 C++ 開發,有用到比較新的 C++ 標準語法,至少要 VC2017,本想直接上到 VC2022,但安裝過程會警告跟 Windows 10 不合,就沒有安裝 VC2022 了。

這裡是為了避免 Community 版商業使用的問題,因為 Build Tools 的授權跟 Community 不同,個人用的話應該直接安裝 Community 就可以。

我只打勾基本【Visual C++ build tools】和【通用Windows 平台建置工具】。

02. 安裝 vcpkg

建議路徑為 C:\src\vcpkg,故在 C:\src 下執行下面指令。

git clone https://github.com/microsoft/vcpkg
.\vcpkg\bootstrap-vcpkg.bat

03. 安裝 PCL

打開【適用於 VS 2017 的 x64 Native Tools 命令提示字元】,切到 C:\src\vcpkg 路徑。

vcpkg install pcl:x64-windows

執行上面指令會順便安裝其他相關模組,其中編譯 PCL 過程最久,我的電腦花了 2 hours,全部是 2.722 hours。

04. 執行 vcpkg integrate install 

這個步驟不確定是否要執行,但因為我後面有遇到其他問題,我有回過頭來做這個步驟,故不確定是否是必須?但我在第二台電腦整個重做還是有做這個動作。

---------------------------

測試 PCL

01. 使用官方 pcd_write.cpp 範例

02. 使用官方 CMakeLists.txt 範例

但必須加上 set(PCL_DIR "C:/src/vcpkg/installed/x64-windows/share/pcl"),否則 cmake 過程中會失敗。

03. 執行 cmake

cmake . -A x64

上面那個 -A 是關鍵,否則下面步驟一直會失敗。

04. build pcd_write.cpp

cmake 後會產生 VC 的專案檔,但因為我們只有 Build Tools,故使用 msbuild 產生執行檔。

msbuild pcd_write.sln

沒有意外的話,在 Debug 目錄下就會有執行檔,並且還會把相關 dll 複製到該目錄。

2022/08/22 更新

試了幾個範例都沒有什麼問題,直到試了一個 visualization 的範例,會說找不到相關的標頭檔,看起來是用到 VTK,使用 vcpkg list 查詢,確實是沒有 VTK,網路上找了一下,要用 vcpkg install pcl[visualization]:x64-windows 的方式才會有 VTK,可惜我在編譯 VTK 時,會發生內部編譯器錯誤,網路上查了一下似乎跟 VTK 還有 PCL 版本有關?也許是要換 VC2019?但懶得重新編譯了,直接安裝 VC2019 + 官方編譯的版本。

步驟如下

01. 安裝 VC2019

步驟同 VC2017。

02. 安裝官方版本

預設會安裝在 C:\Program Files\PCL 1.12.1,另外 OpenNI2 似乎也被一併安裝了,路徑為 C:\Program Files\OpenNI2。

安裝以後,環境變數會多一個 PCL_ROOT 以及其他 OpenNI2 的相關變數,故我們就不用去改 CMakeLists.txt 了。

隨便拿一個範例來試,看起來這樣就可以了,cmake 已經內建在 VC2019。

有些範例需要 OpenNI2.dll,去 C:\Program Files\OpenNI2\Tools 複製一份到執行檔路徑即可,或是把這個路徑加到 PATH,程式執行時會在 PATH 環境變數下尋找。

2022/08/25 更新

又看了一些討論,覺得 vtk 應該要沒問題才對,懷疑跟我測試的電腦 VC 版本太多有關?重新以 vcpkg install pcl[core,qt,vtk]:x64-windows 重 build,果然一切順利完成。

這次再執行 vcpkg integrate install 後,出現提示可以加上下面參數在使用 cmake 時。
 
-DCMAKE_TOOLCHAIN_FILE=C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake

之後改用 cmake . -A x64 -DCMAKE_TOOLCHAIN_FILE=C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake,就不用再自己定義相關 PCL_DIR 等等。

這次連 Qt 的範例都可以順利完成,唯一可惜的是 Qhull 不知為何沒有成功?

之後有空再繼續嘗試。

2022/08/29 更新

終於解決了 Qhull 這個錯誤 (AllInOne)
surface features related to qhull will be disabled

只要設定下面 Windows 環境變數
set QHULL_DIR=C:\Program Files\PCL 1.12.1\3rdParty\Qhull\lib\cmake\Qhull

convex_hull_2d 的官方範例便可以順利編譯了(為了順利執行,還得把 C:\Program Files\PCL 1.12.1\3rdParty\Qhull\bin 加到 Windows 環境變數 PATH)

但 vcpkg 使用同樣的一招還是無法成功。

2022/09/09 更新

找到 vcpkg Qhull issue 的解決方式了,假設 cmake 後的 VC 專案檔為 AAA.vcxproj,找到所有前置處理器定義的 DISABLE_QHULL,把它全移除掉即可,這樣編譯 Qhull 相關就可以成功了。

另外,-DCMAKE_TOOLCHAIN_FILE 這招有時會失敗,可以在 CMakeList.txt 裡面加上 find_package(PCL CONFIG REQUIRED),不要使用官方或網路範例指定版本的寫法。

2022/09/27 更新

又找到另一個 vcpkg Qhull issue 的解決方式。

在 cmake 時加上 cmake . -A x64 -DCMAKE_TOOLCHAIN_FILE=C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_CXX_FLAGS_INIT="-UDISABLE_QHULL"

則在編譯時,會先 /D DISABLE_QHULL  再 /U DISABLE_QHULL,故最後就不會有這個 define,這個方式比前一個解決方式簡單。另外,有試過 cmake 的 remove_definitions(/DDISABLE_QHULL) 無法成功,但用 add_definitions(/UDISABLE_QHULL) 是可以的。

結論:

Fix Qhull issue

AllInOne
set QHULL_DIR=C:\Program Files\PCL 1.12.1\3rdParty\Qhull\lib\cmake\Qhull

vcpkg 
add_definitions(/UDISABLE_QHULL)  or  -DCMAKE_CXX_FLAGS_INIT="-UDISABLE_QHULL"

2022年7月28日 星期四

HyRead 7.8 吋彩色電子紙閱讀器預購

好久沒有寫文章了,最近工作的東西實在沒有辦法寫出像樣的感想,因為我大概還處在襁褓的階段吧XD

今天是 HyRead 這台機器預購的日子,限量 100 台,特價 10,999 的機器,在我中午吃飯時看已經售完,再來 11,999 的機器,在我當下寫文章的時候都還能下單。

也算是記錄一下幾家知名廠商預購的狀況吧?

在我看來,感覺是每下愈況,參與過的幾台機器,個人覺得當初 mooInk Pro 10 吋的預購最踴躍。

2022年6月14日 星期二

WFH 所需頻寬統計

Wi-Fi 訊號一直很差,WFH 視訊開會時確實造成不少困擾,故重要會議時都改用手機 USB 網路分享,手機一直插著這樣下去不是辦法,還好我有一個預付卡門號,上面還有幾 G 可用,買了一個 4G USB 網卡來改善 WFH 辦公環境好提升工作效率。

在偶爾上上網查詢資料的情況下,随便看一下流量統計似乎都不到 20MB。

今天在開了 2 個小時又 7 分鐘會議的情況下,使用 Skype Bussiness 約莫用了 500 MB 流量。

2022年6月6日 星期一

上週生活雜感

上星期因為測試進去辦公室兩天,再加上遇到一些問題心中頗有感觸,不得不提筆記錄一下。

首先是在研究 C++ 書籍時,無意間看到 tinlans 大神回答網友的某篇文章,看到大神在回覆文章時,還不厭其煩的先搜尋一下對方的發文才決定如何回答 C++ 參考書籍的問題,這才是理工人該有的素養,實事求是,可惜我的 Level 不夠,無法遇到這樣的隊友,真希望我有大神的萬分之一功力就好,我現在也不會被 C++ 搞到好煩XD

再來是進辦公室後遇到網路問題,也算是被折騰了一下,後來終於在快下班時把所有想法都搞定,可以悠閒的觀察測試結果。還好我有帶 Elipsa 進去,在觀察測試結果時,可以邊看一下書避免無聊,雖然因為不想多帶翻頁器導致無翻頁器可用,但因為兩年前有開發過軟體翻頁器,馬上拿出我的手機使用這個軟體,一邊按著音量鍵翻頁看書,一邊又可以觀察測試結果避免 miss,真是聰明的工作方式呀?


最後則是我的書房越來越潮濕了,目前看來是外牆的防水層沒了,導致書房的兩面對外牆都是濕氣,不是不想花錢找蜘蛛人搞定,但以裝潢修繕業的陋習來看,在沒有熟識的人介紹下,你肯多花錢都不一定可以找到有良心的施工廠商!還好我的爸媽已經不住在這裡,不然對他們的身體健康一定不好。

有時候敗家就是一個爽字而已

最近買了四樣東西,都是我考慮好幾天以上才購買的東西,甚至其中有一項東西我可能考慮了兩年有吧XD

第一個是 Supernote A6 X,購買它的原因是被討論區的某位社友形容燒到,包括內建 Kindle App、PDF 可支援裁邊,再加上略輸給 reMarkable 2 的手寫體驗,我大概考慮了一兩個星期有,後來還是拿起我的魔法小卡勇敢的給它刷下去,可惜因為疫情關係,現在應該還躺在對岸倉庫中XD


第二個是 OWON VDS1022I,兩年前在開發翻頁器時,因為需要製作升壓或降壓電路,想來看一下供電電源是否穩定,不過因為價格確實較高,故當初並沒有購買。最近因為某些原因,我需要研究一下示波器,剛好又買了幾顆穩壓 IC 想要配合 3D 列印做一支漂亮一點的翻頁器,再加上那麼貴的電子閱讀器前後買了十台有,吃飯的工具不買一台似乎說不過去?於是在端午節前夕終於收到它本人,目前的感想就是一分錢一分貨呀,不過我最不滿意的是它的 UI 過於陽春,也不方便測量,如果有機會可以研究它 USB 封包的格式,我想自己來寫 UI 應該是比較好用?但暫時先這樣用即可。



第三個是 Nintendo Switch OLED,既然都買了示波器,乾脆一不做二不休的連電動都買了,另外還買了兩個數位版遊戲,我終於可以玩到去年就想玩的《暗黑破壞神 2 重製版》了!不過坦白說,可能是人老了,覺得玩遊戲很浪費時間,這應該也是四樣中我最後悔購買的東西,之後再視情況買幾個瑪莉歐的遊戲來玩玩,看看是否能從中找到玩遊戲的樂趣?我想這應該跟我童年本來就沒有一直在玩遊戲有關,絕對不是說任天堂不好,畢竟我還是很喜歡任天堂的《太空戰士三代》,這是我童年唯一自己購買的卡匣,它應該也是我人生當中覺得最好玩的遊戲無誤。

最後則是 NeoFlam FIKA 鑄造不沾炒鍋 26CM,由於我平常用的是父母搬走後留下的不鏽鋼炒鍋,雖然是雙人牌的,但坦白說不太好用,尤其煎蛋時那一層遺留蛋屑,都讓人覺得很阿雜,雖然阿淇博士常說什麼要注意萊頓弗羅斯特現象,但我有那麼厲害我就去當特級廚師了還做什麼工程師XD

終於在前天悠哉的星期六購物時,因為不用特別買生鮮食品可以去 HOLA 閒逛後,入手了這隻鍋子,試用的感想就是為什麼不早點買,我想我的廚藝能力至少有加 30% 有,大概可以算是我心目中的傳說廚具之一。


後來我上網查了一下,好像很多人用了半年後還是會沾鍋,不過我就是把它當陶瓷鍋用,不沾只是附加的好處,幾個月後再來看看是否開始會沾鍋呢?

2022年6月2日 星期四

阿伯出事了XD

好久沒有關於 UEFI 的文章了!雖然我幫自己及同事寫了很多 UEFI Sell 下的小程式,但大部份都是基於 pure C 的程式,很少有用到 UEFI 相關的東西,最多用到一些 SetVariable 以及呼叫兩個 Services 的 API 居多。

今天為了檢查前天進辦公室跑的測試問題,很早就進來辦公室,居然發現是因為網路的問題而不是我原本想的系統問題?然而最近幾次進辦公室都有用 Wireshark 來檢查 ARP 廣播封包的數量好確保 UEFI 網路可以正常工作,我們公司的人確實大部份都是 WFH,故不像以前有七八十趴的 ARP 廣播封包,況且出問題時是凌晨四點多鐘,我是不相信那時候公司有什麼人啦!但你知、我知、獨眼龍也知 UEFI network stack 本來就只是堪用,實在不建議拿來用在專案上,無奈我只是個細漢,只好一直面對這種跟程式無關的 issue。

說也湊巧,前一天也是為了解決跟我自己程式無關的 issue(UB,嚴格來說是未定義行為),更新了一些 code 來做防衛駕駛,既然前一個測試被中斷了,想說還是先花一點時間來跑測試驗證這個問題好結案,不然真的很阿雜。沒想到中途又一直遇到網路問題,此時又拿出了 Wireshark 來檢查 ARP 廣播封包,發現一樣剩不到 15%,故應該不是廣播封包問題?

在我使出了任何絕招都無效後,正準備發個郵件問一下 IT 公司網路最近是否有異動?但據我之前經驗,除了廣播封包這個問題外,我們 IT 在收到申請網路特殊用途後,其實不太會去改變申請的網路設定,無奈一時又沒有其他想法!

就在這個 moment,我突然想到好幾年前,我們開始一個新專案後,我本來用的 UDK base 似乎也要跟著更新,當初我最後用的是 UDK2018,不然網路就是會有奇怪的問題,此時 Wireshark 看到的現象就是掉封包或是 network stack 有很多奇怪的行為。剛好今年 WFH 時,我並沒有特別準備 UDK2018 來 build 我的網路程式,而是延用另一個 tool 內建的 UDK base,雖然我無法看出是那個版本,但我直覺應該是 UDK2014 左右的 base。

知道問題後並不是就沒事了,我以後要怎樣避免這個 UDK base 的問題?雖然說寫文件可以解決這個問題,但我們公司的專案並沒有很系統的規劃,導致文件散落一地,我想就算我寫了文件,其他人也不見得遇到網路問題就會想到是這個原因而來我寫文件的資料夾找答案(這就是沒有系統規劃專案的壞處,沒有固定的地方來放文件,所以你也不會有事就去找文件)?

本想 Google 看看是否有 UDK base 的相關 define 來做編譯檢查,無奈這是個很冷門的問題,我用英文在網路上找不到答案。

我又試著用 file search 關鍵字的技巧,看能不能硬在 UDK base 裡找到 define,無奈用了 UDK、2018、VERSION 等關鍵字都沒有幫助,因為這個搜尋的結果太多,我不太可能一個一個 review,只能粗略的看一眼但仍然沒有答案。

最後我決定在 edksetup.bat 做手腳,我在檔案開頭加了以下指令:

echo #define UDK2018 > Stdlib\Include\ABC.h

然後我在我程式的 main.c 加了一個 #include <ABC.h> 並寫清楚註解以提醒後人。

因為我只在我公司電腦的 UDK2018 base 加了這個 trick,故當我這個專案被別人用在別的 UDK base 就一定會遇到 compile error,此時他看我的註解就知道問題是什麼,這樣就達到提醒的作用了,因為那個別人也包括未來的我XD

就在寫此文章的同時,又突然想到用 2.7(UEFI_Spec_2_7,目前最新是 2.8)來搜尋,果然在 MdePkg\Include\Uefi\UefiSpec.h 找到一些 defines,故我們可以用 EFI_SPECIFICATION_VERSION 是否等於 0x20046 或是 EFI_2_70_SYSTEM_TABLE_REVISION 這個 define 是否存在,並配合 #error 這個前置處理器語法來觸發 compiler error。

2022年5月26日 星期四

消失的記憶 - NTFS

一直到剛剛終於有時間拿出《File System Forensic Analysis》一書來複習一下消失的記憶!

NTFS 雖然是微軟最常使用的檔案系統之一,但因為並沒有公開的規格書,故網路上的資料都有一些不齊全之處。

記得我當初回答同事問題時,也是在網路上找了許久,最後才找到這本書有比較詳盡的描述。

但我印象當初看時,好像也是有一半的地方是看不懂的?

趁著這次重看的機會,看是否能把它搞懂?

---------------------------------------------------------------------

Q1:
為何有些 MFT Entry(FILE RECORD) 資料會有 $BITMAP(0xB0) ,有些就又沒有,他出現的時機是什麼?因為實際的資料不是在 $DATA(0x80) 裡面就可以取到了?

Ans:


Q2:
Metadata 中的 $MFT 大約會拿硬碟的 12.5, 25, 37.5, 50% 的空間來放 $MFT,有的 $MFT 會拿連繼的空間,有的取 $MFT 就要自己去 $DATA 的 DATA RUN 裡面取。

MFT Zone Reservation IS NOT STORED ON DISK
MFT Zone (reserved space for MFT)
1 = 12.5%
2 = 25.0%
3 = 37.5%
4 = 50.0%
Where is this stored on disk?

Ans:
我的猜測如下,對應到 MFT Zone 的位置的 $BITMAP 會被設為 1,表示被使用中,故只有微軟作業系統知道放在哪裡,我想那個表示被使用中的 Entry 如果跳到該 Entry 看,應該是空的。

如果今天 MFT Entry 都用完了,是不是表示就是硬碟滿了?之前有實驗建一個 10MB 的硬碟,用小檔把 MFT Entry 全用滿,後來就沒法再建檔案/目錄了,不過如果 1K空間(MFT Entry)還夠,還是可以建 ADS。

Ans:我覺得是,但我想嘗試去填滿它(Active Disk Editor),寫入失敗。順帶一提,我寫的是 $BITMAP 這個 meta data 指到的 Data Run 位置,但我不確定這樣對嗎?還是應該也改 $MFT meta data 的 $BITMAP attribute(我這兩邊讀到的位置不一樣,不確定是不是我算錯了,差了 1K)?

補充:我搞混了,$MFT 的 $BITMAP attribute 是針對 MFT Entry 的,$BITMAP 的 Data Run 是針對 Cluster 的,那天不知為何一時想混了。


另一個硬碟滿的條件,那就是只用一個檔案,讓他內容超大,ex: 10MB HD 為例,檔案大於 7~8MB ,那 $BITMAP 裡面的Cluster空間就都會被用掉。

上述是否正確,或是還有什麼情況下,NTFS 會爆掉?

Ans:我也只能想到這兩種,但我直覺會先讓 MFT Entry 爆掉,之後一定無法新增檔案了。

Q 3:
目錄都會有 $INDEX_ROOT(0x90),當目錄下檔案多時,就會有 $INDEX_ALLOCATION (0xA0),0x90是 Resident 而 0xA0 是 Non-Resident 的,如果是 0xA0 INDX 申請出來的空間,不會在 $MFT 裡面,所以今天如果只取到 $MFT 想處理目錄,就沒法靠 0x90/0xA0 做 B+Tree 的列舉,就只能自己靠 $MFT 裡面的 0x30 裡面的 Parent directory file record number 去做處理了對嗎?

Ans:
我只知道從 $. parse 的方法,我不知道可以從 $MFT 找到根目錄的方法,而且 0x30 我以為是指 $FILE_NAME attribute?我不確定這邊的 Parent directory file record number 是指什麼?