為什麼選擇 Foxglove 做視覺化
Jetson Nano B01 資源極度有限,卻要跑完整的 ROS 2 Humble + Arduino 繼電器控制 + Reed Switch 回報 + 遠端即時監控。
- 原生支援 ROS 2
- 直接吃 foxglove_msgs,自訂 Panel 方便,不需要手動自行規劃版面尺寸
- 可同時監看 /platform/relay、/platform/reed_switch、/platform/arduino_health topic
- 手機、筆電、平板遠端都能開,部署彈性高
環境準備
1
2
3
| sudo docker run -it --rm --runtime nvidia --network host --privileged \
-v ~/ros2_ws:/ws \
dustynv/ros:humble-desktop-l4t-r32.7.1
|
重點錯誤記錄與排除
錯誤 1:apt 金鑰過期,無法安裝任何套件
現象
The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 7FA2AF80F9C2B8E9
解決指令
移除舊的密鑰和配置
1
2
| sudo rm /usr/share/keyrings/ros-archive-keyring.gpg
sudo rm /etc/apt/sources.list.d/ros2.list
|
下載並安裝新 ROS 2 簽名密鑰
1
| sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
|
RUN
錯誤 2:Foxglove Bridge 編譯失敗
現象
stderr: foxglove bridge CMake Error at CMakeLists.txt:174 (message): Could not find catkin
解決指令
安裝(Github & RapidJSON)
1
2
3
4
5
6
7
| cd /ws/src
git clone https://github.com/foxglove/foxglove-sdk.git
git clone https://github.com/facontidavide/rosx_introspection.git
apt-get install -y rapidjson-dev
|
處理(Insert and find) sensor_msgs
1
2
3
4
5
6
7
| cd /ws/src/foxglove-sdk/ros/src/foxglove_bridge
sed -i '2i find_package(sensor_msgs REQUIRED)' CMakeLists.txt
sed -i '2i find_package(geometry_msgs REQUIRED)' CMakeLists.txt
head -n 5 CMakeLists.txt
|
Clean and RUN
1
2
3
4
5
6
7
8
| cd /ws
rm -rf build/install/log/
source /opt/ros/humble/install/setup.bash
colcon build --symlink-install --base-paths src/rosx_introspection src/foxglove-sdk/ros/src/foxglove_bridge
|
find / -name “foxglove_bridge” and “CMakeLists.txt” → 確保 pwd
錯誤 3:C++17 語言特性無法識別(std::optional、std::string_view 編譯錯誤)
現象
dustynv 映像預設的 GCC 版本太舊(7.5.0),不完整支援 C++17,rosx_introspection 和 foxglove_bridge 都大量使用 C++17 新特性。
解決指令
安裝設置(GCC 8)
1
2
3
4
| apt-get install -y g++-8
export CC=gcc-8
export CXX=g++-8
|
- 使用 C++17 標準
- 不要把警告當錯誤
- 連結檔案系統函式庫
1
| export CXXFLAGS="-std=c++17 -Wno-error -lstdc++fs"
|
Clean
1
2
3
4
5
| cd /ws
# 清理緩存
rm -rf build/install/log/
rm -rf build/foxglove_bridge install/foxglove_bridge
|
手動補丁-1
1
2
3
4
| echo '#include <cstddef>
#if __cplusplus < 201703L
namespace std { enum class byte : unsigned char {}; }
#endif' > patch.txt
|
手動補丁-2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| SDK_INC_DIR="/ws/build/foxglove_bridge/_deps/foxglove_sdk-src/include/foxglove"
if [ -d "$SDK_INC_DIR" ]; then
echo "找到 SDK 資料夾,開始修補"
# 搜尋所有的 .hpp 檔案
find "$SDK_INC_DIR" -name "*.hpp" | while read filename; do
# 把 patch.txt 的內容接上原本的檔案,存成 temp
cat patch.txt "$filename" > temp.hpp
# 用 temp 覆蓋原本的檔案
mv temp.hpp "$filename"
echo "已修補: $filename"
done
echo "✅ 所有檔案修補完成!"
else
echo "❌ 錯誤:找不到 build 資料夾。請確認你剛剛有執行過 colcon build 且沒有刪除 build/。"
fi
|
Environment setting(強制使用 C++17 編譯)
1
2
3
4
5
6
7
8
9
| source /opt/ros/humble/install/setup.bash
colcon build --symlink-install \
--base-paths src/rosx_introspection src/foxglove-sdk/ros/src/foxglove_bridge \
--cmake-args \
-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_CXX_FLAGS="-std=c++17"
export CXXFLAGS="-std=c++17"
|
缺失補入
1
2
3
4
5
| cd /ws/src/foxglove-sdk/ros/src/foxglove_bridge
sed -i '2i set(CMAKE_CXX_STANDARD 17)' CMakeLists.txt
sed -i '3i set(CMAKE_CXX_STANDARD_REQUIRED ON)' CMakeLists.txt
sed -i '4i link_libraries(stdc++fs)' CMakeLists.txt
|
RUN
1
| colcon build --symlink-install --base-paths src/rosx_introspection src/foxglove-sdk/ros/src/foxglove_bridge
|
Arduino 控制節點的設計思考與安全考量
目標是長期 7×24 小時穩定控制 4 路繼電器 + 讀取 Reed Switch。實作過程中最在意的幾個思考點如下:
- CPU 必須極低 → 放棄 10ms 輪詢,改用 serial.readline() 完全阻塞式讀取,CPU 長期 <1%
- 指令不能被任意注入 → 嚴格白名單,只接受 ‘1’~’4’ 四個字元
- 必須明確知道 Arduino 是否還活著 → 1 秒發送 PING,5 秒內無 HEARTBEAT 就標記不健康
- 斷線要自動重連並即時更新健康狀態 → 任何 SerialException 都觸發重連機制
結論
採用 Docker Environment → Upgrade development tools → Lock ROS 2 → Create closed loop 的部署策略,最終實現三個獨立 ROS 2 節點(Bridge、Controller Node、Visualizer Node)在資源受限的 Jetson Nano B01 上穩定運行。底層 Arduino 程式碼內建鎖定式 Failsafe 機制,確保通訊中斷時優先維護硬體安全。整個部署過程記錄的錯誤與解法,希望能幫助遇到類似問題的開發者快速排除障礙。
graph TD
A[Docker Environment] --> B[Upgrade Development Tools]
B --> C[Lock ROS 2 Humble]
C --> D[Create Closed Loop]
D --> E[Bridge Node<br/>Foxglove Bridge]
D --> F[Controller Node<br/>Arduino Relay Control]
D --> G[Visualizer Node<br/>Foxglove Studio]
F --> H[Arduino 硬體層]
H --> I[鎖定式 Failsafe 機制]
E -.通訊協定.-> G
F -.Serial 通訊.-> H
style A fill:#b3d9ff,stroke:#0066cc,color:#000
style B fill:#ffe6b3,stroke:#cc8800,color:#000
style C fill:#ffb3d9,stroke:#cc0066,color:#000
style D fill:#b3ffb3,stroke:#00cc00,color:#000
style E fill:#ffcccc,stroke:#cc0000,color:#000
style F fill:#ffcccc,stroke:#cc0000,color:#000
style G fill:#ffcccc,stroke:#cc0000,color:#000
style I fill:#ff9999,stroke:#990000,color:#000