|

運用研華ASR-A701DVK開發套件輕鬆實現AI機器人應用

   

作者:洪銘恩

傳統機器人開發以AMR 為例,都是圍繞在眾多感測器與主控電腦之間的演算法實現。透過光學雷達或是深度相機量測環境的深度與距離,再透過導航演算法操控機器人在指定的路線中移動。看似機器人能認得當下的環境,才能做出這些移動行為。但實際上並不代表它能理解環境中的每個事物。它只是明白了附近有障礙物,不是真的認得前方是幾位正在行走的路人,或是知道擋在左邊的是另一台正在搬貨的機器人。

VLM/VLA 對機器人開發的時代意義

VLM 的出現提高了機器人理解影像的能力,有別於物件偵測模型只能標示出畫面中的物件,VLM 能進一步理解這些物件之間的關係。像是YOLO 只能標示出畫面中有一個人、刀叉、盤子與牛排。而VLM 則能提供「畫面中有一個人在吃飯」,這樣進一步的資訊。

VLA 則是在VLM 的基礎上增加了Action 功能,使得機器人透過攝影機理解狀況後,還能操控身上的部件去完成後續的動作。例如在雜亂的環境透過手臂精準的抓取指定物品,或是做出摺衣服這樣需要比較多段動作的任務。從VLM 開始到現在VLA 的技術演化,為機器人領域帶來更多的可能性。

ASR-A701DVK 規格開箱

筆者拿到的測試套件是搭載NVIDIA® Jetson Orin™ NX 16GB 核心,並附上兩個GMSL 介面的深度相機。打開盒子一目了然,完全就是主打機器人視覺應用的套件,還非常貼心的提供了不只一個深度相機。如果有研究視覺里程計的玩家就會知道,單靠一個攝影機,若是環境特徵不夠多樣,一旦拉大移動距離,其準確度就會逐漸下降。雖然就定位而言,一般場景兩個深度相機就夠用了,但ASR-A701DVK 支援連接4 個GMSL 介面的攝影機,讓使用者可以依照任務需求添加。

SSD 是128 GB,出廠時已安裝Ubuntu 22.04 LTS + JetPack 6.1,包含Advantech SUSI 與相機驅動的部份,開箱即用,使用者不用為了配件還要尋找相應的SDK。

常見的連接介面像是USB Port、HDMI 與RJ45 網路連接孔,還有刷系統相關的USB Port,一個都沒有少,甚至比起其它同樣搭載Orin NX 的kit 多了不少 。

隨附的深度相機是ORBBEC Gemini 335Lg,可室內與戶外兩用,支援IP65 防塵防水,深度量測達20 m 以上。提供RGB、Depth、雙目IR與內建IMU 感測器和多相機同步。

詳細規格細節可以參考研華提供的規格文件

研華 Robotic Suite 機器人開發流程工具

當我們要建構一個機器人系統,目前最流行的就是安裝ROS2,並根據目標任務安裝相關套件,例如製作一個AMR 或許就需要Navigation 2 導航套件,並根據感測器類型選擇SLAM 方法與里程計算法。如果想導入AI 辨識功能,就得安裝Pytorch 或是Tensorflow。

研華提供了Robotic Suite 機器人開發工具,直接幫大家整合了在NVIDIA Jetson 平台上常用的工具,省去需要個別安裝套件的困擾。筆者有幸直接試用最新的Robotic Suite,新版的部份預計於3月底的時候發佈,到時候就可以在研華GitHub 上下載的到。

現在直接帶大家來看一下新的Robotic Suite,為我們使用者提供了那些功能。當我們進到安裝選單時,總共有8 個選項可以選擇,我們可以分成三個部份來看:

  • 編號1~4 開頭為ISAAC 的這幾個選項,是提供NVIDIA Isaac ROS 的功能。
  • 編號5~7 開頭為ROS2 的這幾個選項,是提供基於光學雷達有關建圖導航的功能。
  • 最後編號8 則是提供目前開源的自動駕駛框架Autoware。

不管是哪個功能都是基於ROS2 系統。

雖然我們這個套件只有提供深度相機,並沒有光學雷達或是移動平台的硬體部份。但是這些功能我們還是可以安裝並執行,每個功能會有範例程式以及提供ros2bag 錄製的數據,執行這些範例時會自動播放數據,不用真的接入感測器也能看到執行效果。

筆者直接在沒有連接深度相機的情況下,執行一個需要深度相機的範例試試看。我們選擇安裝「ISAAC ROS Advanced: Multi-Sensor Function」這個選項。

安裝過程中需要等待一段時間,筆者之前已安裝過「Isaac ROS Development Environment」,但這次在終端機訊息中看到,如果是選擇其它跟ROS 有關的選項,似乎都會自動安裝Isaac ROS Environment。所以大家可以放心地直接選擇自己想要測試的範例即可,不用照順序安裝。不過筆者還是推薦可以每個都打開來玩一次,能對目前機器人的應用上有一些粗略的了解,等到訊息出現「Install [ ] completely」,就表示已安裝完成囉。

接著我們可以在以下路徑找到剛剛安裝好的功能範例:

<pre>/usr/local/Advantech/ros/container/ros-demokit/

我們剛剛安裝的功能範例會在isaac_ros_kit 資料夾裡,ISAAC 系列都會放在一起 (如果是其它功能則例外,它們會有自己的資料夾),以及待會執行時會需要播放的數據,已經放在rosbag 資料夾了。

這時候移動到「isaac_ros_kit」並在這個資料夾內開啟終端機,並輸入以下指令執行範例程式:

<pre>./launch_isaac.sh advanced_examples/isaac_ros_multi_sensor_demo

成功執行後會自動彈出RViz2 觀測視窗,如下圖所示。從畫面中可以看到這個Multi-Sensor Function 範例執行了物件偵測 (Object Detection)、語義分割 (Semantic Segmentation)、Nvblox、Visual SLAM 與顯示深度相機的RGB 圖像和Depth 圖像,可謂視覺應用大禮包。

以筆者過往經驗來看,從乾淨系統到執行上述一些功能,都是要花上不少時間才能執行的。而Robotic Suite 幫我們將這些複雜的手續都包了,真的是非常方便。

使用 Robotic Suite 進行 AI 機器人開發示範案例

為了避免不同專案之間套件衝突的問題,Robotic Suite 採取的是Docker Container 的管理方式。我們執行過的每個範例都會自建一個容器,可以透過以下指令查詢已經存在的容器:

<pre>docker ps -a

既然已經有現成的環境,我們就可以挑選一個符合的,直接進到這些容器裡面去進行後續的開發。Robotic Suite 在Home 目錄底下有自動新建了一個”workspaces” 資料夾,所有的容器都會指向這個資料夾,方便大家存取程式碼。

現在就為大家示範如何導入ASR-A701DVK 隨附的兩個深度相機,並在現實環境中運行Isaac ROS Visual SLAM。在進行以下內容之前,筆者有預先跑過Robotic Suite 關於這個部份的範例「./launch_isaac.sh basic_examples/isaac_ros_visual_slam」,所以在查詢容器時,可以找到名稱為「isaac_ros_visual_slam」的容器。

接著我們需要將兩個深度相機連接在ASR-A701 上,並且相機本身需要固定安裝位置。在執行Visual SLAM 時,需要告訴演算法目前相機的位置與方向,如果位置不固定或安裝的不穩,里程計運算會不準確。所以筆者透過3D 列印的方式,製作了相機支架,並分配一個深度相機朝前方,另一個朝後方。這樣的用意是在當前方的特徵點不夠時,後方的深度相機能補足。

為了方便到處移動,增加了顯示螢幕與提把,並另外加了一個風扇。然後找了一顆符合輸入電壓規格的電池供電。

 

硬體的部份搞定了,接下來就是軟體部份。大致上有幾個步驟需要修改:

  1. 修改多個深度相機發佈的程式。
  2. 自訂isaac_ros_visual_slam launch程式。
  3. 進入容器內編譯程式與執行。

a. 修改多個深度相機發佈的程式

在”workspaces” 資料夾裡面,可以找到Robotic Suite 已經建好的深度相機套件,路徑如下:

<pre>/home/ubuntu/workspaces/orbbec_ros2/src/OrbbecSDK_ROS2/orbbec_camera/examples/gmsl_camera/

在這個路徑底下能找到「multi_gmsl_camera_synced.launch.py」這個程式,我們會修改它,以便同步啟動兩個實際的深度相機。

首先要自己新增這兩個相機的設定檔案,主要關閉一些不必要的發佈訊息。目前這兩個設定檔並不存在,等等我們會新增它們,並放在對應的config 資料夾中。

<pre>[cc]package_dir = get_package_share_directory("orbbec_camera")

launch_file_dir = os.path.join(

package_dir, "examples/gmsl_camera"

)

config_file_dir = os.path.join(package_dir, "config")

 

camera_01_config_file_path = os.path.join(config_file_dir, "camera_01_params.yaml")

camera_02_config_file_path = os.path.join(config_file_dir, "camera_02_params.yaml")

接著我們需要針對兩個相機的實際位置,發佈靜態的tf。例如筆者以ASR-A701 正中心為base_link,並量測兩個相機的左眼,相對於base_link 的絕對座標。

這一步是為了告訴isaac_ros_visual_slam 算法,我們兩個相機在現實中的位置與關係,以便能將接收到的數據對應上實際的位置。

<pre>tatic_tf_camera_01 = Node(
    package='tf2_ros',
    executable='static_transform_publisher',
    name='static_tf_pub_camera_01',
    arguments=['0.125', '0.0475', '0', '0', '0', '0', 'base_link', 'camera_01_link']
)

static_tf_camera_02 = Node(
    package='tf2_ros',
    executable='static_transform_publisher',
    name='static_tf_pub_camera_02',
    arguments=['-0.125', '-0.0475', '0', '3.14', '0', '0', 'base_link','camera_02_link']
)

然後設定兩個相機的發佈,主要會以”serial_number”來區分兩個相機。

<pre>launch1_include = IncludeLaunchDescription(

PythonLaunchDescriptionSource(

os.path.join(launch_file_dir, "gemini_330_gmsl.launch.py")

),

<em>launch_arguments</em>={

"camera_name": "camera_01",

"serial_number": "CPBHA530008S",

"device_num": "2",

"sync_mode": "secondary_synced",

"gmsl_trigger_fps": "3000",

"enable_gmsl_trigger": "true",

"config_file_path": camera_01_config_file_path,

"attach_to_shared_component_container": attach_to_shared_component_container_arg,

"component_container_name": component_container_name_arg,

}.items(),

)

 

launch2_include = IncludeLaunchDescription(

PythonLaunchDescriptionSource(

os.path.join(launch_file_dir, "gemini_330_gmsl.launch.py")

),

<em>launch_arguments</em>={

"camera_name": "camera_02",

"serial_number": "CPBHA530004R",

"device_num": "2",

"sync_mode": "secondary_synced",

"config_file_path": camera_02_config_file_path,

"attach_to_shared_component_container": attach_to_shared_component_container_arg,

"component_container_name": component_container_name_arg,

}.items(),

)

相機個別的”serial_number” 可以在包裝盒上找到。

最後新增剛剛提到的config 檔案,來到以下路徑:

<pre>/home/ubuntu/workspaces/orbbec_ros2/src/OrbbecSDK_ROS2/orbbec_camera/config/

新增「camera_01_params.yaml」,主要開啟左右IR 影像與IMU 資料流,其餘功能關閉。

<pre>enable_ir_auto_exposure: false
ir_exposure: 5000
ir_gain: 24
enable_laser: false
enable_left_ir: true
left_ir_width: 640
left_ir_height: 480
left_ir_fps: 30
left_ir_format: 'Y8'
enable_right_ir: true
right_ir_width: 640
right_ir_height: 480
right_ir_fps: 30
right_ir_format: 'Y8'
enable_color: false
enable_depth: false
enable_sync_output_accel_gyro: true
accel_rate: '200hz'
accel_range: '4g'
gyro_rate: '200hz'
gyro_range: '1000dps'

 b. 自訂isaac_ros_visual_slam launch程式

我們新增一個新的「isaac_ros_visual_slam_orbbec_multi.launch.py」,用來輸入我們實體相機的資料,並啟動isaac_ros_visual_slam 功能。特別是remappings 的地方,要確實填入我們兩個深度相機會發佈的主題。

<pre>mport launch
from launch_ros.actions import ComposableNodeContainer, Node
from launch_ros.descriptions import ComposableNode

def generate_launch_description():
    visual_slam_node = ComposableNode(
        name='visual_slam_node',
        package='isaac_ros_visual_slam',
        plugin='nvidia::isaac_ros::visual_slam::VisualSlamNode',
        parameters=[{
                    'num_cameras': 4,
                    'denoise_input_images': False,
                    'rectified_images': False,
                    'enable_debug_mode': False,
                    'debug_dump_path': '/tmp/cuvslam',
                    'enable_slam_visualization': True,
                    'enable_landmarks_view': True,
                    'enable_observations_view': True,
                    'map_frame': 'map',
                    'odom_frame': 'odom',
                    'base_frame': 'base_link',
                    'input_imu_frame': 'camera_01_gyro_optical_frame',
                    'enable_imu_fusion': True,
                    'gyro_noise_density': 0.000244,
                    'gyro_random_walk': 0.000019393,
                    'accel_noise_density': 0.001862,
                    'accel_random_walk': 0.003,
                    'calibration_frequency': 200.0,
                    'img_jitter_threshold_ms': 33.00
                    }],
        remappings=[('visual_slam/image_0', '/camera_01/left_ir/image_raw'),
                    ('visual_slam/camera_info_0', '/camera_01/left_ir/camera_info'),
                    ('visual_slam/image_1', '/camera_01/right_ir/image_raw'),
                    ('visual_slam/camera_info_1', '/camera_01/right_ir/camera_info'),
                    ('visual_slam/imu', '/camera_01/gyro_accel/sample'),
                    ('visual_slam/image_2', '/camera_02/left_ir/image_raw'),
                    ('visual_slam/camera_info_2', '/camera_02/left_ir/camera_info'),
                    ('visual_slam/image_3', '/camera_02/right_ir/image_raw'),
                    ('visual_slam/camera_info_3', '/camera_02/right_ir/camera_info')]
    )

    visual_slam_launch_container = ComposableNodeContainer(
        name='visual_slam_launch_container',
        namespace='',
        package='rclcpp_components',
        executable='component_container',
        composable_node_descriptions=[
            visual_slam_node,
        ],
        output='screen'
    )
    return launch.LaunchDescription([visual_slam_launch_container])

c. 進入容器內編譯程式與執行

我們可以透過docker 指令啟動已存在的容器並進入,這裡筆者要進入的容器名稱為”isaac_ros_visual_slam”,請開啟一個新的終端機並輸入以下指令:

<pre>docker start isaac_ros_visual_slam docker exec -u admin -it  isaac_ros_visual_slam bash

接著進到工作空間內編譯程式碼:

<pre>cd ../orbbec_ros2 colcon build --symlink-install

編譯完成後不要忘記source 工作空間,現在讓我們啟動深度相機並開始發佈影像,請執行我們剛剛修改的launch 程式碼:

<pre>ros2 launch orbbec_camera multi_gmsl_camera_synced.launch.py

接著打開另一個終端機,同樣使用docker 指令進入同一個容器,並記得source 工作空間,以便載入新的設定。然後找到我們剛剛新增的第二個程式「isaac_ros_visual_slam_orbbec_multi.launch.py」,於相同目錄底下執行指令開啟這個程式:

<pre>ros2 launch isaac_ros_visual_slam_orbbec_multi.launch.py

執行完上述功能之後,兩個深度相機將會發佈各自的左右眼影像,其中一個深度相機會發佈IMU 數據。此時isaac_ros_visual_slam 將會去訂閱它們,並計算里程計與執行視覺SLAM。   為了方便我們觀測,我們需要啟動RViz2 觀測視窗來查看目前運作的結果。請再開啟另一個終端機並進到容器內,執行容器內已經設定好的RViz2 檔案:

<pre>rviz2 -d $(ros2 pkg prefix isaac_ros_visual_slam --share)/rviz/default.cfg.rviz

筆者試著移動剛剛製作的手提裝置,看起來是正常執行的。圖中白色點是影像提取的特徵點,綠色線則是移動軌跡。

試著在室內空間隨意繞了一圈並回到原點,查看RViz2 內的裝置座標是否偏移,從結果來看還蠻準確的。

為了比對雙深度相機的好處,筆者特地關閉一個相機,並重新設定isaac_ros_visual_slam 去訂閱單個深度相機的數據,之後一樣繞行同樣的空間,以下是獲得的結果,可以看到在某個轉彎處跑偏了。

ASR-A701DVK 與VLM、VLA

雖然Robotic Suite 目前沒有提供關於VLM 或VLA 範例,不過在未來的規劃中,研華會將VLM 與VLA 放入Robotic Suite。並且會增加多平台的支援性與更多Robotics 相關的主題,就讓我們期待那天的到來吧!

但這不代表我們目前無法執行這些功能,只是要勤勞一點而已。畢竟ASR-A701DVK 搭載的是NVIDIA® Jetson Orin™ NX,跑個小模型還是沒問題的。

以下是筆者使用ASR-A701DVK 執行Live VLM WebUI 的結果,過程當然沒有像剛剛單安裝一個Robotic Suite,就包下所有功能安裝和模型轉換那麼方便。除了Live VLM WebUI 本身,還需要自己接後台與下載模型。

從上圖中可以看到,我讓VLM 去看一個畫面,畫面中有一雙手正操作著鍵盤與滑鼠,旁邊有放一支手機。紅框內的文字是模型推論結果,它很聰明地描述了圖中的狀況。有別於其它圖像辨識模型,像是物件偵測或語意分割,就只能區分畫面中有什麼物件。

結論

做為工業機器人的控制核心,ASR-A701DVK 大大減少了開發時間,直接幫你包了環境安裝與各個套件的繁雜手續。不但提供AMR 機器人常用的功能,也提供使用者二次開發的方法。硬體上也支援不少連接插座和常用的通訊方式,讓建置機器人更方便。搭配的兩個深度相機,經測試在室內執行V-SLAM 的效果也相當優秀。 如果真的要挑一個缺點的話,我只能說:不要去摸散熱鰭片,很燙!

(責任編輯:謝嘉洵。)

SkyTruth:用衛星監控與遙測進行環境保護

訂閱MakerPRO知識充電報

與40000位開發者一同掌握科技創新的技術資訊!

Author: 洪銘恩

Share This Post On

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *