Quantcast
Channel: CAVEDU教育團隊技術部落格
Viewing all articles
Browse latest Browse all 673

AMR ROS2光達搬運機器人- AI物體距離偵測-使用NVIDIA Orin Nano

$
0
0

前言

接續先前的 ROS 系列文章,本篇文章將會分享AMR ROS2光達搬運機器人在AI上的延伸應用,文章內容共有兩段:

第一段是了解如何應用獲得的深度影像,使用StereoLabs ZED 2i深度影像攝影機,從深度影像中取得畫面中心與相機的實際距離

第二段則是將深度影像的應用與AI影像辨識融合,結合上一篇中Jetson Inference ROS2套件detectnet的物件偵測功能,測量偵測到的物件與相機之間的距離

如果還沒有閱讀過前兩篇關於AI影像應用的文章,可以先往回閱讀之前的文章,會更容易了解這次所分享的內容:

AMR ROS2光達搬運機器人-分段路徑規劃與即時影像串流-使用NVIDIA Orin Nano

AMR ROS2光達搬運機器人-AI即時影像推論Jetson Inference-使用NVIDIA Orin Nano

攝影/撰寫 楊子賢 材料表

 

時間 3小時
難度 3(滿分5)

本文

軟硬體背景

  • NVIDIA Jetson Orin Nano
  • StereoLabs ZED 2i
  • Jetpack 5.1.1
  • L4T 35.3.1
  • Ubuntu 20.04 LTS

利用ZED深度影像攝影機取得畫面中心的距離

作為深度影像攝影機,StereoLabs ZED 2i理所當然的可以取得影像的深度,官方也有準備了範例,可以取得影像中心與攝影機的實際距離。在Orin Nano上使用ZED 2i攝影機的方法可以參考之前的文章,內容有提到如何建立並執行ZED攝影機的Docker容器:

首先要建立一個ZED攝影機的Docker容器

docker run --runtime nvidia -it --rm --privileged --network=host \

  --ipc=host --pid=host \

  -e NVIDIA_DRIVER_CAPABILITIES=all \

  -e DISPLAY \

  -v /dev:/dev \

  -v /tmp/.X11-unix/:/tmp/.X11-unix \

  -v $HOME/.Xauthority:/root/.Xauthority \

  -v ${HOME}/zed_docker_ai/:/usr/local/zed/resources/ \

  --name zed_container \

  zed_ros2_l4t_image:latest

在Docker容器中,開啟ZED攝影機ROS2套件與Rviz

ros2 launch zed_display_rviz2 display_zed_cam.launch.py camera_model:=zed2i

接著開啟另外一個終端機,連接到剛才的ZED攝影機Docker容器,並載入ROS2設定檔,才能夠執行下方的範例程式

docker exec -it zed_container bash

source /ros_entrypoint.sh

source install/setup.bash

執行深度距離範例,接著在終端機中就會輸出現在畫面中央與攝影機的距離

ros2 run zed_tutorial_depth zed_tutorial_depth --ros-args -r depth:=/zed/zed_node/depth/depth_registered

 

下方是範例中使用的程式碼,這邊有特別註記需要使用正確的服務品質設定(QoS, Quality of Service)才能接收到從ZED套件傳過來的訊息,這邊建立了一個名為depth_qos的服務品質設定,它會盡可能地取得攝影機發布的訊息,並且只會接收新取得的資料。

利用準備好的設定建立一個訂閱者,訂閱來自ZED ROS2套件,名為depth的深度影像訊息,這樣就完成範例程式中關於訂閱的初始設定

關於服務品質的設定與相容性請參考ROS2官方文件

接著要設定訂閱的回呼函式,每當收到訊息後,系統就會呼叫一次這個函式,處理接收到的訊息。為了讀取深度影像的內容,首先要將接收到的影像訊息內容轉為指標(Pointer),這樣就能用影像上的位置,推斷需要的數值在記憶體的所在位置。接著再使用訊息中影像的長寬,找出影像的中心位置,取出記憶體中對應位置的數值,就得到畫面中央與攝影機的距離。

結合影像辨識與深度影像取得物體的距離

有了從深度影像取得距離的方法後,就可以搭配上一篇文章中使用到的Jetson Inference ROS2影像辨識套件,先使用物件偵測來取得物體的位置後,再透過深度影像取得物體與攝影機的距離\

在終端機中開啟ZED深度攝影機的容器,並執行ZED ROS2套件

docker run --runtime nvidia -it --rm --privileged --network=host \

  --ipc=host --pid=host \

  -e NVIDIA_DRIVER_CAPABILITIES=all \

  -e DISPLAY \

  -v /dev:/dev \

  -v /tmp/.X11-unix/:/tmp/.X11-unix \

  -v $HOME/.Xauthority:/root/.Xauthority \

  -v ${HOME}/zed_docker_ai/:/usr/local/zed/resources/ \

  -name zed_container \

  zed_ros2_l4t_image:latest

ros2 launch zed_wrapper zed_camera.launch.py camera_model:=zed2i

在另外一個終端機開啟Jetson Inference的容器,並執行Jetson Inference ROS2套件

cd ~/jetson-inference

docker/run.sh --container dustynv/ros:humble-pytorch-l4t-r35.3.1

ros2 run ros_deep_learning detectnet --ros-args -r /detectnet/image_in:=/zed/zed_node/rgb/image_rect_color

再使用一個終端機開啟AMR Docker容器,執行detect_depth套件與RQT,等待程式啟動完成,在RQT的ImageView畫面中選擇 “/detectnet/person_depth”,就可以看到偵測到的物體距離

./run_docker.sh

rqt -s image_view & ros2 run detect_depth detect_depth

STEP1:初始設定

執行後程式所做的第一步是進行初始設定,總共會訂閱三個主題訊息,分別是來自ZED攝影機ROS2套件的深度影像depth_registered、來自Jetson Inference ROS2套件物件偵測程式detectnet的物件資訊detections,以及偵測結果的影像overlay,並發布一個包含物體距離的影像:名為person_depth的影像訊息

這邊使用了message_filter套件當中的訊息同步Approximate Synchronizer,只要設定好訂閱者與接收的時間範圍,它可以把時間相近的訊息整合在一個回呼函式中,以便處理來自不同訊息中的資料

STEP2:轉換影像訊息內容

第二步是在接收到訊息後呼叫的回呼函式當中,跟前面的範例程式相同,將接收到的深度影像訊息內容轉為指標,並保存影像的寬度,後續計算物體在影像上的位置時會使用到。還有使用cv_bridge套件將偵測結果影像訊息轉為容易修改的OpenCV格式,方便之後加上計算出來的距離數值

STEP3:計算物體位置

第三步一樣是在回呼函式當中,從物件偵測訊息中取出物體在影像上的中心座標,利用前面保存的畫面寬度,計算物體在畫面裡的位置,取出記憶體中對應的深度數值。為了避免同時有多個物體時,畫面會被大量的數字覆蓋,這邊把深度數值的精度調整到小數點後兩位,利用OpenCV繪製在偵測結果影像上。如果有不只一個物體被偵測到,就重複執行這一步,直到所有物體都處理完成,最後再用cv_bridge套件把OpenCV格式的結果影像轉換成ROS2影像訊息並發布

使用Rviz或是RQT訂閱上面發送的person_depth影像訊息就可以看到帶有距離數值的結果影像,圖中數字單位為公尺。

以上是ROS2搬運機器人結合專業景深攝影機的深度影像應用,後續會繼續分享ROS2上的各種應用,敬請期待喔!

AMR ROS2光達搬運機器人- AI物體距離偵測-使用NVIDIA Orin Nano〉這篇文章最早發佈於《CAVEDU教育團隊技術部落格》。


Viewing all articles
Browse latest Browse all 673

Trending Articles