機器人作業系統(Robot Operating System,ROS)提供了許多軟體函式庫和工具,協助建構機器人應用,包括框架、演算法、感測器和機器人平台。其廣受世界各地的機器人專家和研究人員採用。生態系統的套件和函式庫持續湧入,使機器人專案的入門變得更容易。
NVIDIA Isaac SDK 是可以加速開發與部署 AI 機器人的開放式機器人平台。Isaac SDK 帶來一個可以在 NVIDIA Jetson 平台上,以及在 GPU 上高效率處理的軟體框架 Isaac Engine。其同時包含 AI 和 GPU 加速演算法 Isaac GEM,並與 Isaac Sim 整合,以利用 NVIDIA RTX 進行真實感模擬。使用 Isaac SDK ROS 橋接器,即可在以 ROS 為基礎的應用程式堆疊中使用這些功能(圖 1)。讓開發人員和研究人員可以利用這兩個平台建構機器人應用。
本文示範如何使用 ROS 橋接器,從 ROS 格式的攝影機拍攝影像,並將其與 Isaac GEM(Superpixel)搭配使用。透過範例,我們也可以瞭解如何使用 Isaac ROS 橋接器,將 Isaac GEM 和 Isaac Sim 與 ROS 應用程式堆疊及模組進行連接。最後將說明如何為 ROS 轉 Isaac 或 Isaac 轉 ROS 情境編寫訊息轉換器(ROS 橋接器)。
開始著手
首先,在電腦上安裝 ROS 和 Isaac SDK。您可以使用 ROS 橋接器進行以下操作:
bazel run packages/ros_bridge/apps/ros_to_superpixels roslaunch realsense2_camera rs_rgbd.launch
或者,您可以下載及儲存 ROS bag:
roslaunch realsense2_camera rs_from_file.launch rosbag_filename:="PathToRosBag"
圖 2 所示為 ROS 橋接器的實際畫面。ROS 攝影機影像(或在 ROS rviz 中視覺化的 ROS bag)是饋送至稱為 Superpixel 的 Isaac SDK GEM(在 Isaac Sight 中視覺化)。下一節將介紹如何進行。
ROS 影像上的 Isaac Superpixel GEM
在 Isaac SDK 中有許多經過 GPU 加速的電腦視覺演算法,Superpixel(超像素)為其中之一。超像素是外觀相似的相連像素群組。超像素分割可將影像分成為數百個非重疊的超像素,而不是數千或數百萬個個別像素。利用超像素,可以在更具有意義的區域上運算特徵,以及減少使用演算法的輸入實體數量。有許多複雜性和效能各異之不同的超像素演算法。Isaac SDK 具有使用於 RGB-D 影像的 GPU 加速超像素建置。
在此範例中,是從 ROS 產生 RGB-D 輸入感測器訊息。之後,Isaac Superpixels GEM 會使用此 ROS 影像產生超像素分割。
首先,在 NVIDIA Jetson 裝置上安裝 ROS。欲深入瞭解與 Isaac SDK 搭配使用的 ROS 安裝需求,請參閱 Install ROS。您可以在偏好的任何 Jetson 裝置上完成此操作。
接著將 RGB-D 攝影機(例如 Realsense 435d)連接至 Jetson 開發人員套件。您也可以使用 ROS Realsense rosbag,例如 structured.bag。若想要啟動 ROS Realsense 攝影機驅動程式,以及開始產生色彩和深度 sensor_msg 類型,請遵循說明。
您需要 ROS 橋接器轉換器,將 ROS 訊息轉換成 Isaac 影像深度 proto 訊息(如先前的範例所示),以供 Isaac Superpixels GEM 使用。修改現有的 RosToImage 轉換器,將 ROS 深度訊息納入現有的色彩影像訊息中。請在已下載 Isaac SDK 的開發工作站上執行此操作(圖 3)。
bool RosToImage::rosToProto(const sensor_msgs::Image::ConstPtr& ros_message, std::optional& ros_time, alice::ProtoTx& tx_proto) { ros_time = ros_message->header.stamp; auto builder = tx_proto.initProto(); std::vector& buffers = tx_proto.buffers(); // This converter is currently only supporting rgb8 color encoding and 16UC1 depth encoding if (ros_message->encoding == "rgb8") { ImageConstView3ub rgb_image = CreateImageView<uint8_t, 3>(static_cast(&ros_message->data[0]), ros_message->height, ros_message->width); Image3ub color_image(rgb_image.dimensions()); Copy(rgb_image, color_image); show("image", [&](sight::Sop& sop) { sop.add(rgb_image); }); ToProto(std::move(color_image), builder, buffers); } else if (ros_message->encoding == "16UC1") { // ROS depth image with 16UC1 encoding is of type uint8_t ImageConstView1ui16 image = CreateImageView<uint16_t, 1>( reinterpret_cast(&ros_message->data[0]), ros_message->height, ros_message->width); Image1f depth_image(image.dimensions()); ConvertUi16ToF32(image, depth_image, 0.001); ToProto(std::move(depth_image), builder, buffers); } else { reportFailure("Unsupported image format: %s", ros_message->encoding.c_str()); return false; } builder.setRows(ros_message->height); builder.setCols(ros_message->width); builder.setDataBufferIndex(0); return true; }
圖 3 所示為 ROS 主題轉 Isaac proto 的流程。
- ROS 轉換器分別使用 RosToImage 和 RosToCameraIntrinsics,將 ROS depth/Color 和 Camerainfo 主題轉換成 Isaac proto。
- SuperPixel 短程式碼使用 ROS 攝影機驅動程式影像產生超像素分割。
以下程式碼範例是說明 Isaac app.json 檔案如何尋找 ROS 橋接器轉換器邊緣和配置:
{ "name": "ros_to_superpixels", "modules": [ "sight" ], "graph": { "nodes": [ { "name": "ros_to_perception", "subgraph": "packages/ros_bridge/apps/ros_to_perception.subgraph.json" }, { "name": "superpixels", "subgraph": "packages/superpixels/apps/superpixels.subgraph.json" } ], "edges": [ { "source": "ros_to_perception.subgraph/interface/color", "target": "superpixels.subgraph/interface/color" }, { "source": "ros_to_perception.subgraph/interface/depth_intrinsics", "target": "superpixels.subgraph/interface/depth_intrinsics" }, { "source": "ros_to_perception.subgraph/interface/depth", "target": "superpixels.subgraph/interface/depth" } ] }, "config": { "ros_to_perception.ros_converters": { "RosToDepth": { "channel_name": "/camera/depth/image_rect_raw" }, "RosToCameraIntrinsics": { "channel_name": "/camera/color/camera_info" }, "RosToImage": { "channel_name": "/camera/color/image_raw" } } }
現在,從開發工作站,將應用程式部署在 Jetson 裝置上:
bob@desktop:~/isaac$ ./engine/build/deploy.sh --remote_user <username_on_robot> -p //packages/ros_bridge/apps:ros_to_superpixels-pkg -d jetpack43 -h <robot_ip>
在 Jetson 裝置上,使用自訂的應用程式名稱執行應用程式:
bob@jetson:~/$ cd deploy/<bob>/ros_to_superpixels/ bob@jetson:~/deploy/<bob>/ros_to_superpixels$ packages/ros_bridge/apps/ros_to_superpixels
最後,使用 Isaac Sight 檢查 Superpixels GEM 的輸出。
針對 ROS 導航堆疊使用 Isaac Global Localization GEM
ROS 導航堆疊可因為使用 Isaac SDK GPU 加速 Global Localization GEM 解決機器人綁架問題而受益。
Isaac SDK 2020.1 版本提供在使用 Global Localization GEM 的 Isaac Sim Unity3D中,引導 ROS TurtleBot 3 Waffle Pi 的範例。以下範例為包含 Isaac Sim 等內容的完整應用程式,但是 ROS 使用者可以僅使用 Global Localization GEM。
從本文章之脈絡,回顧 Isaac 版本文件中的範例應用程式。首先,請瞭解 ROS 主題使用之不同的 Isaac ROS 橋接器轉換器。圖 4 所示為具有 Isaac Global Localization GEM 之 ROS TurtleBot3 應用程式,使用的各種 Isaac ROS 橋接器轉換器。Isaac Global Localization 使用的 ROS 橋接器為 PoseMessageToRos,將輸出 /initialpose 發布至 ROS TurtleBot3 應用程式。
Isaac PoseMessageToRos 轉換器的作用如下:從 Isaac 中,將 Global Localization 演算法的輸出接收為 PoseTreeEdgeProto::Reader,並將 initialpose 主題發布至 ROS。此轉換如以下程式碼範例所示。
bool PoseMessageToRos::protoToRos(PoseTreeEdgeProto::Reader reader, const ros::Time& ros_time geometry_msgs::PoseWithCovarianceStamped& ros_message) { // Read data from Isaac type const Pose3d pose = FromProto(reader.getPose()); const auto& translation = pose.translation; const auto& rotation = pose.rotation.quaternion(); // Populate data for ROS type ros_message.header.stamp = ros_time; ros_message.header.frame_id = get_frame_id(); ros_message.pose.pose.position.x = translation.x(); ros_message.pose.pose.position.y = translation.y(); ros_message.pose.pose.position.z = translation.z(); ros_message.pose.pose.orientation.x = rotation.x(); ros_message.pose.pose.orientation.y = rotation.y(); ros_message.pose.pose.orientation.z = rotation.z(); ros_message.pose.pose.orientation.w = rotation.w(); if (get_report_success()) { reportSuccess(); } return true; }
現在,請查看 ROS 橋接器轉換器的實際運作情形。執行以下命令,以啟動 small-warehouse 場景:
bob@desktop:~isaac_sim_unity3d/builds$ ./sample.x86_64 --scene small_warehouse --scenarioFile ~/isaac/packages/navsim/scenarios/turtlebot3_waffle_pi.json --scenario 0
執行同時與 Isaac Sim Unity3D 和 ROS 通訊的 Isaac SDK 應用程式:
bob@desktop:~/isaac$ bazel run packages/ros_bridge/apps:ros_to_navigation_unity3d -- --more apps/assets/maps/virtual_small_warehouse.json --config ros_navigation:packages/ros_bridge/maps/small_warehouse_map_transformation.config.json, ros_navigation:packages/ros_bridge/apps/ros_to_navigation_turtlebot3_waffle_pi.config.json
在 ROS 中啟動 TurtleBot3:
TURTLEBOT3_MODEL=waffle_pi roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=$(realpath packages/ros_bridge/maps/small_warehouse.yaml)
在輸出中,Isaac Sim 顯示機器人是根據 ROS 導航前往目標,而 ROS 導航也是使用 Isaac Global Localization GEM。您可以從 Isaac 端,在 Isaac Sight 中監視機器人,或從 ROS 端,在 rviz 中監視。請在 Sight 中拖曳地圖視窗的 pose_as_goal 標記,以變更導航目標。
開發自訂 ROS 橋接器轉換器
在圖 3 和圖 4 中,標準 ROS 成像主題已轉換成 Isaac proto,以在其上執行 Perception GEM。Isaac SDK 具有可以在 ROS 訊息與 Isaac 訊息之間轉換的 ROS 橋接器轉換器。NVIDIA 也具有包含在 Isaac SDK 中的開放原始碼轉換器函式庫。但是,未來可能必須建立一個轉換器。
以下程式碼範例是顯示將 ROS custom_msgs::Custom1 訊息類型,轉換成 Isaac Proto1 訊息類型:
class RosToProto1 : public RosToProtoConverter<Proto1, custom_msgs::Custom1> { public: bool rosToProto(const custom_msgs::Custom1::ConstPtr& ros_message, std::optional& ros_time, alice::ProtoTx& tx_proto) override; };
將 Proto2 類型從 Isaac 轉換成 ROS custom_msgs::Custom2 類型的轉換器,如下所示。
class Proto2ToRos : public ProtoToRosConverter<Proto2, custom_msgs::Custom2> { public: bool protoToRos(const alice::ProtoRx& rx_proto, const ros::Time& ros_time, custom_msgs::Custom2& ros_message) override; };
在 Isaac 應用程式 JSON 配置檔中,將需要的 ROS 主題名稱新增為 channel_name:
"RosToProto1": { "channel_name": "/custom_input", ... }, "Proto2ToRos": { "channel_name": "/result", ... }
isaac.ros_bridge.ImageToRos 短程式碼在 Isaac 應用程式中接收 ImageProto 資料,並將其發布至 ROS。換言之,它將資料從 ImageProto 轉換成 sensor_msgs::Image。
結論
本文章是示範 ROS 開發人員如何使用 NVIDIA Isaac SDK 進行協作。您已經學會如何在現有的 ROS 應用程式中,選擇性使用 Isaac GEM,例如全域局部化、低延遲、高保真感知演算法,而您經常使用的解決方案仍在 ROS 中。您同時學會了如何自訂新的 ROS-Isaac 橋接器轉換器。
我們希望能聽到您使用 Isaac SDK 進行 ROS 協作的經驗。請在 Isaac 論壇上與我們分享您的 ROS 橋接器轉換器和意見。
若需要更多資訊,請參閱以下資源:
- Isaac message API actions 和 Message API Overview — Isaac 2020.1 documentation
- Building Isaac Applications
- Isaac Sight
專為虛擬協作和即時擬真模擬所打造的開放平台 – NVIDIA Omniverse