De modulaire en gebruiksvriendelijke perceptie-stack van NVIDIA Isaac SDK blijft de ontwikkeling van verschillende mobiele robots versnellen. Isaac SDK 2020.1 introduceert de Python API, waardoor het eenvoudiger wordt om robotapplicaties te bouwen voor degenen die bekend zijn met Python.

In dit bericht onderzoeken we deze functie en delen we een stapsgewijze handleiding voor het bouwen van je eigen Isaac-applicaties met Python. We introduceren Python-programmering in Isaac SDK met voorbeelden over het maken van een applicatie; werken met codelets, modules en gegevensstroom; en werken met verschillende gegevenstypen. We sluiten de post af met voorbeelden om subgrafieken toe te voegen aan dezelfde applicatie en deze op Jetson te implementeren. We laten u ook zien hoe u kunt werken met Jupyter-notebooks, een krachtige UI-tool voor Python-ontwikkelaars. Voor meer gevorderde Python-ontwikkelaars hebben we ook voorbeelden toegevoegd van het implementeren van Isaac-apps op een mobiele robot en van een collaboratieve robotarm in IsaacSim.


Figuur 1. Een virtuele robot besturen in IsaacSim met een Jupyter-notebook en de Isaac SDK Python API.

Aan de slag met Python-programmering in Isaac SDK

Om u te begeleiden bij het maken van een Isaac-toepassing in Python, maakt u een mybot.py-toepassingsbestand. Begin met een nieuwe map onder de map met apps, //apps/mybot. Maak een BUILD-bestand met de volgende code en sla het op onder //apps/mybot/BUILD zodat Bazel het kan herkennen.

load(“//engine/build:isaac.bzl”, “isaac_py_app”) isaac_py_app( naam = “mijnbot”, srcs = [“mijnbot.py”], gegevens = [], modules=[], deps = [ “//engine/pyalice”, ], )

In het BUILD-bestand is //engine/pyalice de ondersteunende code van Python API, terwijl mybot.py de robottoepassing is die is gecodeerd in Python. Zet de volgende code in //apps/mybot/mybot.py en voer het uit met bazel run apps/mybot:mybot. Je kunt zien dat het draait door de console-uitbarsting, die je op elk moment kunt stoppen met de klassieke CTRL-C.

van engine.pyalice importeren Aanvraagapp = Toepassing(naam=“mijnbot”)-app.uitvoeren()

Wijs de browser naar http://localhost:3000 terwijl de app draait en je zult niets zien in Sight, de visualisatietool in Isaac SDK.

Kennismaken met codelets, modules en dataflow

Isaac SDK wordt geleverd met veel bouwstenen voor robottoepassingen, codelets genaamd. Zie Component API-overzicht voor meer informatie over de volledige lijst.

Sommige van deze codelets zijn beschikbaar zoals ze zijn, zoals Recorder. Anderen zijn verpakt als modules die expliciet moeten worden geladen voordat de codelets beschikbaar zijn. Voeg de volgende modules toe aan het Bazel BUILD-bestand dat zojuist is gemaakt om ze beschikbaar te maken voor laden.

modules = [ “message_generators”, “kijkers”, ],

Je kunt ze nu laden vanuit Python met de applicatie-instantie die is gemaakt vóór app.run:

app.load_module('message_generators' )-app.load_module('viewers')

In Isaac SDK worden gegevens gegenereerd door sensoren en stromen tussen instanties van codelets totdat ze worden verbruikt door actuatoren. Om instanties van geladen codelets te maken, voegt u de volgende code toe aan de Python-toepassing voordat u app.run aanroept.

node_src =app.toevoegen('src') component_src = node_src.toevoegen(app.register.isaac.message_generators.ImageLoader, 'ImageLoader')

Hier wordt een knooppunt met de naam src gemaakt. Een component van ImageLoader, die wordt geleverd door de module message_generators, wordt gemaakt met de naam ImageLoader en gekoppeld aan het knooppunt van src. Het publiceert beeldgegevens van een gespecificeerd PNG-bestand als ColorCameraProto-berichten alsof ze afkomstig zijn van een echte camera. U kunt de afbeelding specificeren waaruit gegevens moeten worden geladen, evenals verschillende andere parameters (hoewel ze er in dit voorbeeld niet toe doen) en hoe vaak het bericht wordt gepubliceerd. Zie isaac.message_generators.ImageLoader voor meer informatie.

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'] = ' 1 hz'

Om camerabeelden te visualiseren, zou de ColorCameraViewer-codelet helpen. Op dezelfde manier kunt u er een instantie van maken met de volgende code:

node_sink = app.toevoegen('sink') component_sink = node_sink.toevoegen(app.register.isaac.kijkers.ColorCameraViewer, 'ColorCameraViewer' )

Gegevens moeten tussen codelets stromen. U moet er echter wel verbindingen tussen maken om de gegevensstroom te laten verlopen. Uit de documentatie weet je dat CameraGenerator drie uitgangskanalen heeft. Kies het color_left-kanaal waarnaar ColorCameraProto-berichten worden gepubliceerd. Op dezelfde manier zou je kunnen zien dat de ColorCameraViewer-codelet berichten leest van het color_listener-kanaal. Verbind ze (aangeduid als “edge”):

app.verbinden (component_src, >'kleur', component_sink, 'color_listener' )

Voer de applicatie (mybot.py) opnieuw uit en controleer Sight voor de afbeelding, zoals weergegeven in afbeelding 2.

Afbeelding 2. De uitvoer van mybot.py bekijken in Isaac Sight.

Werken met verschillende Isaac-afbeeldingsgegevenstypen in Python

Isaac SDK stelt u in staat om met verschillende gegevensbronnen in uw toepassing te werken:

  • Opgenomen sensorgegevens (vat)
  • Echte sensorgegevens (camera)
  • Gesimuleerde sensorgegevens

In dit gedeelte leggen we uit hoe u met deze gegevenstypen in een Python-toepassing kunt werken.

Werken met camera's

Isaac SDK ondersteunt veel USB-camera's met de V4L2Camera-codelet. Zie Een camerafeed weergeven voor meer informatie.

In deze sectie gebruikt u een Realsense-camera, die wordt ondersteund met de RealsenseCamera-codelet in de module van realsense. Op dezelfde manier kon je de camerabeelden van Sight zien, net als de eerdere afbeelding. Omdat dit een soort drop-in-vervanging van ImageLoader is, kunt u een opdrachtregelargument gebruiken om tussen beide te schakelen. Voor meer informatie over het omgaan met opdrachtregelargumenten in Python, argparse — Parser voor opdrachtregelopties, argumenten en subopdrachten. Je zou zoiets als het volgende codevoorbeeld hebben:

parser = argparse.ArgumentParser( beschrijving='Voorbeeld Python API-app')parser.add_argument.add_argument span>('–source', typ=str, dest='bron', hulp='De bron om gegevens uit te halen', keuzes=['camera', 'afbeelding'], standaard='camera' ) argumenten, _ =parser.parse_known_args() if argumenten.bron == 'afbeelding': app.load_module('message_generators') component_src = node_src.toevoegen(app .register.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.verbinden(component_src, 'kleur',viewer_component, 'color_listener') elif argumenten.bron == 'camera': app.load_module( 'realsense')camera =-app.toevoegen(“cam”).toevoegen(app.register.isaac.RealsenseCamera) camera.config span>.rijen = 480 camera.config.cols = 640camera.config.color_framerate = 30camera.config. depth_framerate = 30 app.verbinden(camera,'color', viewer_component, 'color_listener')-app.run()

Zoals eerder getoond, biedt de Python API flexibiliteit in hoe u omgaan met verschillende omgevingen.

Werken met Cask

Werken met echte sensorgegevens is intuïtief, maar het is misschien niet altijd praktisch om dit te doen. Het vat zou kunnen helpen. Cask is het formaat voor het opnemen van berichten dat wordt gebruikt in de Isaac SDK. In Isaac SDK is het mogelijk om een ​​stroom berichten op te nemen en deze later opnieuw af te spelen voor foutopsporing of analyse. Als u beeldstreams van een Realsense-camera wilt opnemen, probeert u de voorbeeldtoepassing op //apps/samples/camera:record_realsense.

Met een opgenomen vat kun je het altijd en overal opnieuw afspelen en met de berichtenstromen spelen zonder de echte sensor. Stel dat het opgenomen vat zich in de map /home/bob/cask/bevindt. U kunt de berichten ophalen met de Replay-codelet:

player_node = app.toevoegen( 'speler') player_component = player_node.toevoegen(app.register span>.isaac.alice .Herhalen) player_component.config['cask_directory']= '/home/bob/cask'-app.verbinden(player_component, 'color', viewer_component, 'color_listener')

Op dezelfde manier zou je een vat als mogelijke optie kunnen toevoegen aan de Python-applicatie, net zoals je deed met de Realsense-camera. Hier is de naamkleur de kanaalnaam die wordt gebruikt om de beeldstroom van de kleurencamera op te nemen. Dan kun je de stream op Sight bekijken alsof deze van de echte camera komt.

Werken met gesimuleerde sensoren

Zoals eerder beschreven, heb je al een Python-applicatie die kan schakelen tussen geregistreerde sensordata (cask) en echte sensordata (camera). Voeg nu nog een mogelijke gegevensbron toe: de gesimuleerde sensor van IsaacSim Unity3D. Voeg de sim-optie toe aan de opdrachtregelargumentbron en verbind de gesimuleerde cameraberichtenstroom met de viewer voor visualisatie, zoals in het volgende codevoorbeeld:

parser.add_argument('–source', typ= str,dest='bron', help='De bron om gegevens uit te halen' , keuzes=['cask', 'camera', 'image', 'sim'], standaard='sim ') if argumenten.bron == 'afbeelding': elif argumenten.bron == 'cask': elif argumenten.bron == 'camera': elif argumenten.bron =='sim':-app. laden('packages/navsim/apps/navsim_tcp.subgraph.json ')-app.verbinden('interface/output', 'kleur', 'viewer/ColorCameraViewer', 'color_listener' )-app.uitvoeren()

Haal IsaacSim Unity3D op. Zie IsaacSim Unity3D voor meer informatie.

Start IsaacSim Unity3D:

./build/voorbeeld.x86_64 scene medium_warehouse

Standaard is de Python-toepassing probeert te praten met de simulatie op dezelfde host. Als de toepassing op een andere host draait, configureert u de parameter van de host dienovereenkomstig voor componentinterface/-uitvoer. Zie isaac.alice.TcpSubscriber voor meer informatie. Voer de applicatie uit en de beelden van een gesimuleerde camera zijn beschikbaar op Sight, zoals weergegeven in Afbeelding 3.

Afbeelding 3. De uitvoer van de virtuele camera bekijken in Isaac SDK Sight.

De beelden zijn afkomstig van de gesimuleerde camera die op de gesimuleerde robot is gemonteerd. Probeer te spelen met beweegbare objecten zoals de Nano-box op de simulatie-GUI en zie dat de gesimuleerde camera werkt als een echte.

Alles samentrekken met subgrafieken

Zoals je zou kunnen hebben opgemerkt, maken componenten (instanties gemaakt van codelets) en de randen die ze verbinden een grafiek. Dergelijke grafieken kunnen worden geladen vanuit JSON-bestanden en indien nodig vanuit de Python-toepassing worden geladen. Zie Inleiding tot Isaac Robotics Engine voor meer informatie.

De subgraph-pakketten voor simulatiecommunicatie/navsim/apps/navsim_tcp.subgraph.json verpakt bijvoorbeeld knooppunten, componenten en randen voor communicatie met IsaacSim Unity3D of NVIDIA Omniverse via TCP. Om het beschikbaar te maken voor uw toepassing, voegt u de volgende Bazel-gegevensafhankelijkheden toe aan het BUILD-bestand dat u eerder hebt gemaakt:

data = [ “//packages/navsim/apps:navsim_tcp_subgraph”, ],

In de Python-toepassing kan het dan worden geladen met het volgende commando:

app.laden('packages/navsim/apps/navsim_tcp.subgraph.json')

De subgraafcomponent lijkt meer op een recept dat uit een groep knooppunten bestaat dan op een container. Het laden van een subgrafiek lijkt meer op het maken van knooppunten en componenten volgens het recept. In Zicht kon je al die knooppunten (scenario_manager, interface) zien die zijn gemaakt op basis van de subgrafiek (Figuur 4). Door ze te verbinden met andere knooppunten, kunt u meer gecompliceerde toepassingen maken met app.connect.

Afbeelding 4. De rekengrafiek die het gebruik van verschillende subgrafieken laat zien.

Als er meer dan één subgrafiek is geladen, kunnen naamconflicten optreden omdat knooppunten in elke toepassing unieke namen moeten hebben. Om dergelijke conflicten te voorkomen, laadt u de subgraaf met nog een argument:

app.laden( 'packages/navsim/apps/navsim_tcp.subgraph.json', 'simulatie', )

Hier is het tweede argument een “node name prefix” voor alle nodes gespecificeerd in het JSON-bestand. Het bestand packages/navsim/apps/navsim_tcp.subgraph.json specificeert bijvoorbeeld een knooppunt met de naam interface. De eerdere instructie zou een knooppunt maken met de naam simulation.interface, in plaats van interface.

De applicatie implementeren op Jetson

Nu heb je een applicatie in Python. Er is maar één commando nodig om op een echt Jetson-bord te draaien:

./engine/build/implementeren .sh h p //apps/mybot:mybot-pkg – d jetpack43

Zie Aan de slag en implementeren en uitvoeren op Jetson voor meer informatie over het implementeren van applicaties op Jetson.

Maak via SSH verbinding met uw Jetson-bord of open een terminal vanuit de GUI en controleer de map /home/nvidia/deploy/bob/mybot-pkg. Als je verschillende gebruikersnamen gebruikt op Jetson en de ontwikkelingsconfiguratie, vervang dan nvidia door de gebruikersnaam op het Jetson-bord en bob door de gebruikersnaam op de ontwikkelingsconfiguratie.

Voer de applicatie uit op Jetson met het volgende commando:

[email protected]:~/deploy/bob/mybot-pkg$ ./run apps/mybot/mybot.py

Als je bronnen buiten de repository gebruikt, overweeg dan om ze toe te voegen aan Bazel-afhankelijkheden van de applicatie, zodat ze automatisch kunnen worden geïmplementeerd in Jetson, samen met de applicatie, met behulp van deploy.sh.

Als je dat bent gebruik IsaacSim Unity3D op pc en configureer de hostparameter zodat ze goed kunnen communiceren.

Werken met Jupyter-notebooks

Omdat je hier de Python API hebt, werkt een Jupyter-notebook zeker. Gebruik het volgende BUILD-bestand met lege mybot.ipynb:

isaac_jupyter_app(naam = “mijnbot”, modules = [ “message_generators” , “kijkers”, ] , notitieboekje = “mijnbot.ipynb”, )

Implementeer de toepassing op dezelfde manier als het Jetson-bord of X86-werkstation en start Jupyter met de volgende opdracht:

jupyter-notebook-apps/mijnbot/mijnbot.ipynb

Je bent nu klaar om te gaan. De run-functie blokkeert en keert alleen terug als de robottoepassing is gestopt. Om interactief met een robotica-applicatie te spelen, gebruikt u de start- en stopfuncties dienovereenkomstig.

Python gebruiken voor gesimuleerde mobiele robots

In de sectie Werken met gesimuleerde sensoren staat een gesimuleerde robot waarop de gesimuleerde camera is gemonteerd. IsaacSim Unity3D is ontworpen om mobiele robots te simuleren. Voor een voorbeeld van een robottoepassing die een gesimuleerde robot bestuurt met een differentiële basis in IsaacSim Unity3D, raadpleegt u de toepassing op //apps/navsim:navsim_navigate. De componenten en subgrafieken zijn te vinden in het JSON-bestand, apps/navsim/navsim_navigate.app.json. Zie IsaacSim Unity3D voor meer informatie.

Python gebruiken voor gesimuleerde robotarmen

Naast mobiele robots zou de Isaac SDK ook kunnen worden gebruikt om toepassingen voor robotarmen te bouwen. Met Omniverse IsaacSim kun je spelen met gesimuleerde robotarmen zonder de echte hardware. Volg voor meer informatie de sessie-instructies “UR10 in Omniverse IsaacSim” op Simple Joint Control with Jupyter Notebook. De applicatie zou de robotarm in simulatie besturen, zoals weergegeven in figuur 5.

Afbeelding 5. De UR10 van Universal Robots wordt in simulatie bestuurd met een Jupyter-notebook.

Dit is wat er gebeurt in de applicatie. Het eerste is om een ​​subgraaf te laden die communicatie met de simulator via TCP mogelijk maakt.

app.laden(bestandsnaam=“packages/navsim/apps/navsim_tcp.subgraph.json”, voorvoegsel< span class="pun">=“simulatie”)

Om vloeiende bewegingen voor de gewrichten te genereren, laadt u een andere subgrafiek voor knooppunten:

app.laden( bestandsnaam=“packages/planner/apps/multi_joint_lqr_control.subgraph.json”, voorvoegsel=“lqr”)

Deze subgrafiek bevat de knooppunten van de LQR-planner, die opdrachten genereert voor huidige gewrichtstoestanden en doelgewrichtsposities. Verbind de knooppunten voor simulatie met de knooppunten voor de planner om de stroom van berichten over de gewrichtsstatus van de robotarm en commandoberichten ertussen mogelijk te maken:

app.verbinden(simulation_node[“output”],“joint_state”, lqr_interface, “joint_state”)-app.verbinden(lqr_interface, “joint_command”,simulatie_node[“input”], “joint_position”)

Een codelet gecodeerd met Python, PyCodelet JointPositionControl, leest doelgewrichtspositiewaarden van schuifregelaars en publiceert deze waarden als CompositeProto-berichten:

class JointPositionControl(Codelet): defstart(zelf): zelf.tx = zelf.isaac_proto_tx(< span class="str">“CompositeProto”, “commando” ) zelf._widget = CompositeWidget(zelf.config.gewrichten “positie”, zelf.config.limieten) def vink(zelf): zelf.tx._msg = < span class="kwd">zelf._widget.composiet zelf.tx.publiceren()

Zie voor meer informatie Python-codelets maken.

De JointPositionControl-codelet wordt vervolgens aan een knooppunt gekoppeld en verbonden met de LQR-planner doelinvoerkanaal:

widget_node = app.toevoegen(“command_generator”) joint_commander = widget_node.toevoegen(JointPositionControl)-app. verbinden(joint_commander,“commando”, lqr_interface, “joint_target”)

Start de applicatie met app.start en de arm staat tot je beschikking.

Gesimuleerde robotarmen met een gesimuleerde camera

Om een ​​robotarm met een camera te hebben, laadt u in Omniverse IsaacSim het podium omni:/Isaac/Samples/Isaac_SDK/Scenario/sortbot_sim.usd. Start de simulatie en de robotmotorbrug in Omniverse IsaacSim en schakel de viewport van perspectief naar polscamera, zoals weergegeven in Figuren 6 en 7.

Figuur 6. Perspectief van de robot in IsaacSim.

Net als in de vorige toepassing, kunt u het gesimuleerde camerakanaal verbinden met de ColorCameraViewer-codelet om de beelden te visualiseren, en met DepthCameraViewer om de gesimuleerde dieptesensorgegevens te visualiseren.

app.load_module(“kijkers”) kijkers =-app .toevoegen(“kijkers”) color_viewer = kijkers.toevoegen(app.register.isaac.kijkers.ColorCameraViewer, “ColorViewer”)-app.verbinden(simulation_node[“output”], “color”, color_viewer, “color_listener”) depth_viewer = kijkers.toevoegen(app.register .isaac.kijkers span>.DepthCameraViewer, “DepthViewer”)-app.verbinden(simulation_node[“output”], “diepte”, depth_viewer, “depth_listener”) depth_viewer.config.max_visualization_depth = 3

Start de app en de gesimuleerde camerabeelden zouden in Zicht moeten verschijnen:

Figuur 7. Polsweergave van de robot in IsaacSim.

Samenvatting

In dit bericht heb je een robotica-applicatie helemaal opnieuw gemaakt met de Python API. Je hebt de applicatie laten werken met een echte camera, opgenomen cameragegevens en een gesimuleerde camera. We hebben je ook laten zien hoe je kunt werken met een gesimuleerde mobiele robot en een gesimuleerde robotarm met behulp van de Python API. Veel plezier met het bouwen van robots!

Gebruik de volgende bronnen om aan de slag te gaan met de Isaac SDK:

  • Download Isaac SDK release 2020.1 en volg de installatiestappen.
  • Zie Python API in de NVIDIA Isaac-documentatie voor meer informatie.

Isaac SDK 2020.1 wordt geleverd met veel voorbeelden van Python-applicaties, bijvoorbeeld //apps/samples/april_tags:april_tags_python. De bijbehorende Python-code staat in //apps/samples/april_tags/april_tags_python.py. Deze applicatie detecteert specifieke April Tags uit camerabeelden en visualiseert de resultaten. Zie April Tags in de Isaac SDK-documentatie en AprilTag van het April Robotics Laboratory voor meer informatie hierover.

Yang Liu
Software engineer, Isaac SDK, NVIDIA

Qian Lin
Software engineer, Isaac SDK, NVIDIA

Atousa Torabi
Productmanager, Isaac Robotics Team, NVIDIA

Swapnesh Wani
Data Scientist, Solutions Architecture and Engineering Group, NVIDIA

0

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *