NVIDIA ISAAC 軟件開發(fā)工具包 的模塊化和易于使用的感知堆棧繼續(xù)加速各種移動機器人的發(fā)展。 ISAAC sdk2020.1 引入了 Python API ,使那些熟悉 Python 的人更容易構(gòu)建機器人應(yīng)用程序。
在這篇文章中,我們將探討這個特性,并分享如何使用 Python 構(gòu)建您自己的 ISAAC 應(yīng)用程序的分步指南。我們在 ISAAC SDK 中介紹 Python 編程,并舉例說明如何創(chuàng)建應(yīng)用程序;如何使用代碼、模塊和數(shù)據(jù)流;以及如何處理不同的數(shù)據(jù)類型。我們用示例來總結(jié)文章,將子圖添加到同一個應(yīng)用程序中,并將其部署到 Jetson 上。我們還將向您展示如何使用 Jupyter 筆記本電腦,這是一個面向 Python 開發(fā)人員的強大 UI 工具。對于更高級的 Python 開發(fā)人員,我們還提供了在移動機器人上部署 ISAAC 應(yīng)用程序以及在 ISAAC Sim 中部署協(xié)作機器人手臂的例子。
圖 1 。使用 Jupyter 筆記本和 ISAAC SDK Python API 在 ISAAC Sim 中控制虛擬機器人。
ISAAC SDK 中 Python 編程入門
為了指導(dǎo)您使用 Python 創(chuàng)建一個 ISAAC 應(yīng)用程序,請創(chuàng)建一個 mybot.py 應(yīng)用程序文件。從 apps 文件夾下的新文件夾開始, //apps/mybot 。用下面的代碼創(chuàng)建一個構(gòu)建文件,并將其保存在 //apps/mybot/BUILD 下,以便 Bazel 能夠識別它。
ISAAC SDK 中 Python 編程入門
為了指導(dǎo)您使用 Python 創(chuàng)建一個 ISAAC 應(yīng)用程序,請創(chuàng)建一個mybot.py
應(yīng)用程序文件。從 apps 文件夾下的新文件夾開始,//apps/mybot
。用下面的代碼創(chuàng)建一個構(gòu)建文件,并將其保存在//apps/mybot/BUILD
下,以便 Bazel 能夠識別它。
load("http://engine/build:isaac.bzl", "isaac_py_app") isaac_py_app( name = "mybot", srcs = ["mybot.py"], data = [], modules=[], deps = [ "http://engine/pyalice", ], )
在構(gòu)建文件中,//engine/pyalice
是 Python API 的支持代碼,mybot.py
是用 Python 編寫的 robot 應(yīng)用程序。將下面的代碼放入//apps/mybot/mybot.py
并用bazel run apps/mybot:mybot
運行它。您可以通過控制臺 spew 判斷它正在運行,您可以使用經(jīng)典的 CTR L-C 隨時停止它。
from engine.pyalice import Application app = Application(name="mybot") app.run()
當(dāng)應(yīng)用程序運行時,將瀏覽器指向http://localhost:3000,您將在視力中看不到任何內(nèi)容,這是 ISAAC SDK 中的可視化工具。
了解代碼、模塊和數(shù)據(jù)流
ISAAC SDK 為機器人應(yīng)用程序提供了許多構(gòu)建塊,稱為代碼。
其中一些代碼可以按原樣提供,比如錄音機。其他模塊打包為模塊,必須在代碼集可用之前顯式加載這些模塊。將以下模塊添加到剛剛創(chuàng)建的 Bazel 構(gòu)建文件中,以便加載它們。
modules = [ "message_generators", "viewers", ],
現(xiàn)在可以使用在app.run
之前創(chuàng)建的應(yīng)用程序?qū)嵗龔?Python 加載它們:
app.load_module('message_generators') app.load_module('viewers')
在 ISAAC SDK 中,數(shù)據(jù)由傳感器生成,并在代碼實例之間流動,直到它們被執(zhí)行器消耗。要從加載的 codelet 創(chuàng)建實例,請在調(diào)用之前將以下代碼添加到 Python 應(yīng)用程序應(yīng)用程序運行.
node_src = app.add('src') component_src = \ node_src.add(app.registry.isaac.message_generators.ImageLoader, 'ImageLoader')
這里創(chuàng)建了一個名為src
的節(jié)點。消息生成器模塊提供的ImageLoader
的組件以ImageLoader
的名稱創(chuàng)建,并附加到src
的節(jié)點上。它將指定 PNG 文件中的圖像數(shù)據(jù)作為ColorCameraProto
消息發(fā)布,就像它們來自真實的相機一樣。您可以指定要從中加載數(shù)據(jù)的圖像以及其他幾個參數(shù)(盡管在本示例中這些參數(shù)并不重要)以及消息發(fā)布的頻率。有關(guān)詳細(xì)信息,請參閱ISAAC 消息_ generators . ImageLoader。
component_src.config['color_filename'] = '/home/bob/Pictures/panda.png' component_src.config['focal_length'] = [35.0, 35.0] component_src.config['optical_center'] = [300.0, 400.0] component_src.config['tick_period'] = '1hz'
為了可視化攝像機圖像,彩色攝影機代碼將有所幫助。類似地,您可以使用以下代碼創(chuàng)建它的實例:
node_sink = app.add('sink') component_sink = \ node_sink.add(app.registry.isaac.viewers.ColorCameraViewer, 'ColorCameraViewer')
數(shù)據(jù)應(yīng)該在代碼之間流動。但是,必須在它們之間建立連接才能使數(shù)據(jù)流動。從文檔中可以看出,CameraGenerator
有三個輸出通道。選擇ColorCameraProto
消息發(fā)布到的 color _ left 頻道。類似地,您可以看到ColorCameraViewer
代碼從color_listener
通道讀取消息。連接它們(稱為“邊緣”):
app.connect(component_src, 'color', component_sink, 'color_listener')
再次運行應(yīng)用程序(mybot.py
),并檢查 Sight 是否有圖像。
在 Python 中使用不同的 ISAAC 圖像數(shù)據(jù)類型
ISAAC SDK 允許您在應(yīng)用程序中使用多個數(shù)據(jù)源:
- 記錄的傳感器數(shù)據(jù)(容器)
- 真實傳感器數(shù)據(jù)(攝像機)
- 模擬傳感器數(shù)據(jù)
在本節(jié)中,我們將解釋如何在 Python 應(yīng)用程序中使用這些數(shù)據(jù)類型。
使用攝像頭
ISAAC SDK 支持許多帶有V4L2Camera
codelet 的 USB 攝像頭。
在本節(jié)中,您將使用 Realsense 攝像頭,它由realsense
模塊中的RealsenseCamera
代碼集支持。類似地,你可以從視線中看到攝像機鏡頭,就像之前的圖像一樣。因為這是對ImageLoader
的直接替換,所以可以使用命令行參數(shù)在它們之間進(jìn)行切換。有關(guān)如何在 Python 中處理命令行參數(shù)的更多信息,argparse- 命令行選項、參數(shù)和子命令的解析器。您將得到如下代碼示例:
parser = argparse.ArgumentParser(description='Sample Python API app') parser.add_argument('--source', type=str, dest='source', help='The source to get data from', choices=['camera', 'image'], default='camera') args, _ = parser.parse_known_args() if args.source == 'image': app.load_module('message_generators') component_src = \ node_src.add(app.registry.isaac.message_generators.ImageLoader, 'src') component_src.config['color_filename'] = '/home/bob/Pictures/panda.png' component_src.config['focal_length'] = [35.0, 35.0] component_src.config['optical_center'] = [300.0, 400.0] component_src.config['tick_period'] = '1hz' app.connect(component_src, 'color', viewer_component, 'color_listener') elif args.source == 'camera': app.load_module('realsense') camera = app.add("cam").add(app.registry.isaac.RealsenseCamera) camera.config.rows = 480 camera.config.cols = 640 camera.config.color_framerate = 30 camera.config.depth_framerate = 30 app.connect(camera, 'color', viewer_component, 'color_listener') app.run()
如前所示, PythonAPI 提供了處理不同環(huán)境的靈活性。
使用木桶
使用真實的傳感器數(shù)據(jù)是直觀的,但是這樣做并不總是實際可行的。木桶能幫上忙。 Cask 是用于記錄 ISAAC SDK 中的消息的格式。在 ISAAC SDK 中,可以記錄一個消息流,并在以后回放以用于調(diào)試或分析。要從 Realsense 攝像頭錄制圖像流,請嘗試在//apps/samples/camera:record_realsense
運行示例應(yīng)用程序。
有了錄音桶,你可以在沒有真正的傳感器的情況下隨時隨地重放和播放消息流。假設(shè)記錄的容器位于/home/bob/cask/
的文件夾中。您可以使用Replay
代碼來檢索消息:
player_node = app.add('player') player_component = player_node.add(app.registry.isaac.alice.Replay) player_component.config['cask_directory'] = '/home/bob/cask' app.connect(player_component, 'color', viewer_component, 'color_listener')
類似地,您可以向 Python 應(yīng)用程序添加一個 cask 作為一個可能的選項,就像您使用 realseness camera 一樣。這里,名稱color
是用于記錄彩色相機圖像流的通道名稱。然后你就可以查看視頻流,就好像它來自真實的攝像機一樣。
使用模擬傳感器
如前所述,您已經(jīng)有了一個 Python 應(yīng)用程序,可以在記錄的傳感器數(shù)據(jù)( cask )和真實傳感器數(shù)據(jù)( camera )之間切換。現(xiàn)在再添加一個可能的數(shù)據(jù)源:來自 ISAAC Sim Unity3D 的模擬傳感器。將 Sim 選項添加到命令行參數(shù)源,并將模擬相機消息流連接到查看器以進(jìn)行可視化,如以下代碼示例所示:
parser.add_argument('--source', type=str, dest='source', help='The source to get data from', choices=['cask', 'camera', 'image', 'sim'], default='sim') … if args.source == 'image': ... elif args.source == 'cask': ... elif args.source == 'camera': ... elif args.source == 'sim': app.load('packages/navsim/apps/navsim_tcp.subgraph.json') app.connect('interface/output', 'color', 'viewer/ColorCameraViewer', 'color_listener') app.run()
檢索 ISAAC 是 Unity3D。有關(guān)詳細(xì)信息,請參閱ISAAC Sim Unity3D。
啟動 ISAAC 是 Unity3D :
./build/sample.x86_64 --scene medium_warehouse
默認(rèn)情況下, Python 應(yīng)用程序嘗試與同一主機上的模擬對話。如果應(yīng)用程序正在另一臺主機上運行,請為組件interface/output
配置相應(yīng)的主機參數(shù)。有關(guān)詳細(xì)信息,請參閱isaac.alice.TcpSubscriber。運行該應(yīng)用程序,模擬攝像機的鏡頭可以看到。
鏡頭來自安裝在模擬機器人上的模擬攝像機。試著在模擬圖形用戶界面( GUI )上玩一些可移動的物體,比如納米盒子,看看模擬相機的工作原理和真相機一樣。
用子圖把它拉到一起
正如您所注意到的,組件(從代碼創(chuàng)建的實例)和連接它們的邊組成了一個圖形。這樣的圖可以從 JSON 文件加載,也可以根據(jù)需要從 Python 應(yīng)用程序加載。有關(guān)詳細(xì)信息,請參閱 MIG 。
例如,模擬通信子圖packages/navsim/apps/navsim_tcp.subgraph.json
封裝了用于使用 TCP 與 ISAAC Sim Unity3D 或 NVIDIA Omniverse 通信的節(jié)點、組件和邊。要使其對應(yīng)用程序可用,請將以下 Bazel 數(shù)據(jù)依賴項添加到您先前創(chuàng)建的生成文件中:
data = [ "http://packages/navsim/apps:navsim_tcp_subgraph", ],
在 Python 應(yīng)用程序中,可以使用以下命令加載它:
app.load('packages/navsim/apps/navsim_tcp.subgraph.json')
子圖組件更像是由一組節(jié)點組成的配方,而不是容器。加載子圖更像是按照配方創(chuàng)建節(jié)點和組件。在視圖中,您可以看到從子圖(圖 4 )創(chuàng)建的所有節(jié)點(場景管理器、接口)。通過將它們與其他節(jié)點連接,可以使用app.connect
創(chuàng)建更復(fù)雜的應(yīng)用程序。
當(dāng)加載多個子圖時,命名沖突 MIG ht 會發(fā)生,因為在任何應(yīng)用程序中,節(jié)點都需要具有唯一的名稱。若要避免此類沖突,請使用另一個參數(shù)加載子圖:
app.load( 'packages/navsim/apps/navsim_tcp.subgraph.json', 'simulation', )
這里,第二個參數(shù)是 JSON 文件中指定的所有節(jié)點的“ node name prefix ”。例如,packages/navsim/apps/navsim_tcp.subgraph.json
文件指定一個名為interface
的節(jié)點。前面的語句將創(chuàng)建一個名為simulation.interface
的節(jié)點,而不是interface
。
在 Jetson 上部署應(yīng)用程序
現(xiàn)在有了一個 Python 應(yīng)用程序。在真正的 Jetson 板上運行只需要一個命令:
./engine/build/deploy.sh -h -p //apps/mybot:mybot-pkg -d jetpack43
有關(guān)將應(yīng)用程序部署到 Jetson 的更多信息,請參閱入門和在 Jetson 上部署和運行。
使用 SSH 連接到您的 Jetson 板或從 GUI 打開一個終端并檢查文件夾/home/nvidia/deploy/bob/mybot-pkg
。如果您在 Jetson 和開發(fā)設(shè)置上使用不同的用戶名,請將nvidia
替換為 Jetson 板上的用戶名,將 bob 替換為開發(fā)設(shè)置上的用戶名。
使用以下命令在 Jetson 上運行應(yīng)用程序:
nvidia@Jetson:~/deploy/bob/mybot-pkg$ ./run apps/mybot/mybot.py
如果您正在使用存儲庫之外的資源,請考慮將它們添加到應(yīng)用程序的 Bazel 依賴項中,以便可以使用deploy.sh
將它們與應(yīng)用程序一起自動部署到deploy.sh
。
如果您在 PC 機上使用 ISAAC Sim Unity3D ,則可以正常通信。
使用 Jupyter 筆記本
因為這里有 pythonapi ,所以 Jupyter 筆記本肯定可以工作。將以下生成文件與空的mybot.ipynb
一起使用:
isaac_jupyter_app( name = "mybot", modules = [ "message_generators", "viewers", ], notebook = "mybot.ipynb", )
以類似于 Jetson 板或 X86 工作站的方式部署應(yīng)用程序,并使用以下命令啟動 Jupyter :
jupyter notebook apps/mybot/mybot.ipynb
你現(xiàn)在可以走了。 run 函數(shù)被阻塞,只有在 robotic 應(yīng)用程序停止時才返回。要以交互方式使用 robotics 應(yīng)用程序,請相應(yīng)地使用 start 和 stop 函數(shù)。
Python 在模擬移動機器人中的應(yīng)用
在使用模擬傳感器工作的部分,有一個模擬機器人,上面安裝了模擬攝像機。 ISAAC Sim Unity3D 是用來模擬移動機器人的。對于在 ISAAC Sim Unity3D 中控制帶有差分基座的模擬機器人的示例 robot 應(yīng)用程序,請檢查//apps/navsim:navsim_navigate
中的應(yīng)用程序。組件和子圖可以在 JSON 文件apps/navsim/navsim_navigate.app.json
中找到。有關(guān)詳細(xì)信息,請參見ISAAC Sim Unity3D。
用 Python 模擬機器人手臂
除了移動機器人,用 Jupyter 筆記本電腦進(jìn)行簡單的聯(lián)合控制SDK 也可以用于構(gòu)建機器人手臂的應(yīng)用程序。有了Omniverse ISAAC?,你可以在沒有真正硬件的情況下使用模擬機械手臂。有關(guān)更多信息,請按照用 Jupyter 筆記本電腦進(jìn)行簡單的聯(lián)合控制上的“ UR10 in用 Jupyter 筆記本電腦進(jìn)行簡單的聯(lián)合控制用 Jupyter 筆記本電腦進(jìn)行簡單的聯(lián)合控制Sim ”會話說明操作。應(yīng)用程序?qū)⒃谀M中控制機械臂,如圖 5 所示。
以下是應(yīng)用程序中發(fā)生的情況。第一件事是加載一個子圖,允許通過 TCP 與模擬器通信。
app.load(filename="packages/navsim/apps/navsim_tcp.subgraph.json", prefix="simulation")
若要為關(guān)節(jié)生成平滑運動,請為節(jié)點加載另一個子圖:
app.load( filename="packages/planner/apps/multi_joint_lqr_control.subgraph.json", prefix="lqr")
該子圖封裝 LQR 規(guī)劃器的節(jié)點,生成當(dāng)前關(guān)節(jié)狀態(tài)和目標(biāo)關(guān)節(jié)位置的命令。將仿真節(jié)點與規(guī)劃器的節(jié)點連接起來,以使機械臂關(guān)節(jié)狀態(tài)消息和命令消息在它們之間流動:
app.connect(simulation_node["output"], "joint_state", lqr_interface, "joint_state") app.connect(lqr_interface, "joint_command", simulation_node["input"], "joint_position")
用 Python 編碼的代碼集 PyCodeletJointPositionControl
從滑塊讀取目標(biāo)關(guān)節(jié)位置值,并將這些值作為CompositeProto
消息發(fā)布:
class JointPositionControl(Codelet): def start(self): self.tx = self.isaac_proto_tx("CompositeProto", "command") self._widget = CompositeWidget(self.config.joints "position", self.config.limits) def tick(self): self.tx._msg = self._widget.composite self.tx.publish()
有關(guān)詳細(xì)信息,請參見創(chuàng)建 Python 代碼。
然后,JointPositionControl
代碼集連接到一個節(jié)點,并連接到 LQR planner 的目標(biāo)輸入通道:
widget_node = app.add("command_generator") joint_commander = widget_node.add(JointPositionControl) app.connect(joint_commander, "command", lqr_interface, "joint_target")
啟動應(yīng)用程序應(yīng)用程序啟動你可以隨意使用手臂。
帶模擬攝像機的模擬機械臂
在 Omniverse ISAAC Sim 中,要有一個帶攝像頭的機械臂,請加載 stageomni:/Isaac/Samples/Isaac_SDK/Scenario/sortbot_sim.usd
。在 Omniverse ISAAC Sim 中啟動仿真和機器人引擎橋,并將視口從透視切換到腕部攝影機,如圖 6 和 7 所示。
與之前的應(yīng)用程序一樣,您可以將模擬攝影機通道連接到ColorCameraViewer
代碼板以可視化畫面,并將DepthCameraViewer
連接到可視化模擬深度傳感器數(shù)據(jù)。
app.load_module("viewers") viewers = app.add("viewers") color_viewer = viewers.add(app.registry.isaac.viewers.ColorCameraViewer, "ColorViewer") app.connect(simulation_node["output"], "color", color_viewer, "color_listener") depth_viewer = viewers.add(app.registry.isaac.viewers.DepthCameraViewer, "DepthViewer") app.connect(simulation_node["output"], "depth", depth_viewer, "depth_listener") depth_viewer.config.max_visualization_depth = 3
啟動應(yīng)用程序,模擬的攝像機鏡頭應(yīng)該會出現(xiàn)在眼前:
總結(jié)
在本文中,您使用 pythonapi 從頭創(chuàng)建了一個機器人應(yīng)用程序。您使應(yīng)用程序可以使用真實的攝影機、錄制的攝影機數(shù)據(jù)和模擬攝影機。我們還向您展示了如何使用 pythonapi 處理模擬移動機器人和模擬機械臂。做機器人玩得開心!
關(guān)于作者
Yang Liu 是一名軟件工程師,負(fù)責(zé)開發(fā) NVIDIA ISAAC SDK 的各個部分。他獲得了達(dá)拉斯德克薩斯大學(xué)計算機科學(xué)博士學(xué)位。
審核編輯:郭婷
-
API
+關(guān)注
關(guān)注
2文章
1503瀏覽量
62128 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3280瀏覽量
57741 -
python
+關(guān)注
關(guān)注
56文章
4797瀏覽量
84787
發(fā)布評論請先 登錄
相關(guān)推薦
評論