De Robot operativsystem (ROS) er egentlig ikke et operativsystem, men et rammeverk og et sett med verktøy som gir funksjonaliteten til et operativsystem på en heterogen gruppe datamaskiner. Dens nytte er ikke begrenset til roboter, men de fleste verktøyene som tilbys fokuserer på arbeid med perifer hardware.
ROS Den er delt inn i mer enn 2000 pakker, hver pakke har spesialisert funksjonalitet. Antall verktøy som er koblet til rammeverket er trolig dens største kraft.
ROS gir funksjonalitet for maskinvareabstraksjon, enhetsdrivere, kommunikasjon mellom prosesser på flere maskiner, verktøy for testing og visualisering og mye mer.
Nøkkelfunksjonen til ROS er måten programvaren kjører og kommuniserer på, slik at du kan designe kompleks programvare uten å vite hvordan bestemt maskinvare fungerer. ROS gir en måte å koble til et stamnett av prosesser (noder). Noder kan kjøres på flere enheter og koble til huben på forskjellige måter.
De viktigste måtene å opprette et nettverk på er å tilby nødvendige tjenester, eller å definere annonsør- eller abonnentforbindelser med andre noder. Begge metodene kommuniserer gjennom spesifikke typer meldinger. Noen typer leveres av kjernepakker, men meldingstyper kan defineres av individuelle pakker.
Utviklere kan sette sammen et komplekst system ved å koble eksisterende løsninger til små problemer. Måten systemet implementeres på, lar oss:
Bytt ut komponenter med lignende grensesnitt på farten, og fjern behovet for å stoppe systemet for forskjellige endringer.
Multiplekser utgangen fra flere komponenter til en inngang for en annen komponent, slik at du kan løse ulike problemer.
Koble komponenter laget på forskjellige programmeringsspråk ved å bare implementere de riktige kontaktene til meldingssystemet, noe som gjør programvareutvikling lettere ved å koble eksisterende moduler fra forskjellige utviklere.
Lag noder i et nettverk av enheter uten å bekymre deg for hvor en kode kjøres, og implementer kommunikasjonssystemene mellom prosessen (IPC) og den eksterne prosedyreoppringingen (RPC).
Koble direkte til ekstern maskinvare på forespørsel uten å skrive ekstra kode ved å bruke de to foregående punktene.
Vi planlegger å demonstrere hvor nyttig det er ved iterativt å utvikle en enkel løsning. Det er flere viktige fordeler sammenlignet med andre tilnærminger. ROS har støtte på tvers av plattformer og tillater forbindelser mellom prosesser på flere enheter, gjennom peer-tilkoblinger som håndteres bak kulissene. Designet gir støtte for hvilket som helst språk når C ++ kommunikasjonsklasser bestemmes, eller man utvikler klasser manuelt for språkgrensesnittet.
ROS er laget av sitt eget samfunn. Etter flere år resulterte det i et stort antall gjenbrukbare pakker som er enkle å integrere takket være systemarkitekturen.
Alternative tilnærminger som MRPT , CARMEN , LCM , Spiller , Microsoft RDS og andre gir noen, men ikke alle disse funksjonene. Mesteparten av tiden er designfeil begrensninger i språkstøtte, dårlig kommunikasjon mellom prosesser eller mangel på støtte for forskjellige enheter, noe som uten tvil er det vanskeligste problemet å løse.
Siden vårt fokus er rammeverket og ikke algoritmene som sådan, for spesielle problemer, vil det gitte problemet være veldig enkelt. Målet vårt er å bygge programvare for en datamaskin som er en del av prosessen og lar oss fjernstyre og overvåke en robot, koblet til oss via Wi-Fi, ved hjelp av en gamepad på datamaskinen vår og en overføring fra kameraet montert på roboten .
Først og fremst vil vi koble et enkelt program til en enkel simulering, bare for å demonstrere de grunnleggende prinsippene til ROS. Vi skal koble en gamepad til en datamaskin og prøve å utforme et godt kontrollskjema for å overføre gamepad-inngangen til styresignaler for en robot.
De viktigste språkene for å skrive ROS-kode er C ++ og Python, C ++ foretrekkes for lavere ytelse. Vi vil forklare eksemplene våre i Python fordi den har mindre kvalifisering i koden og det ikke er behov for å gjøre en spesifikk konstruksjon.
ROS-versjoner er referert til etter navn. Til dags dato er den siste utgivelsen Jade Turtle , og LTS-versjonen er Indigo iglo . Å gå fra versjon er å foretrekke, og bakoverkompatibilitet er ikke garantert i ROS, så alle eksempler vil bli skrevet for Indigo .
ROS er tilgjengelig på forskjellige * NIX-plattformer. Den offisielt støttede versjonen er på Ubuntu. OS X, Arch Linux, Debian, Raspbian og Android-versjoner støttes av samfunnet.
Vi ser installasjonsprosessen for Ubuntu 14.04 på skrivebordet. Prosesser for alle støttede versjoner og plattformer er tilgjengelige i offesiell nettside . Virtuelle maskiner med allerede installert ROS er også tilgjengelig.
Installasjonen er plattformavhengig (og de fleste plattformer har pakker), men innstillingene for arbeidsområdet er de samme for alle plattformer. .
ROS tilbyr sine egne arkiver. Det første trinnet er å legge dem til.
sudo sh -c 'echo 'deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main' > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116 sudo apt-get update
Deretter vil du ha alle vertspakker for alle ROS-versjoner tilgjengelig for din Ubuntu-versjon. For eksempel støtter Ubuntu 14.04 indigo
og jade
.
Installering av basispakker på skrivebordet har ett av tre alternativer:
sudo apt-get install ros-indigo-ros-base
for minimal installasjon
sudo apt-get install ros-indigo-desktop
å ha det ekstra grunnleggende GUI-verktøyet
sudo apt-get install ros-indigo-desktop-full
å ha alle de offisielle funksjonene, inkludert forskjellige simulatorer og biblioteker for navigering og persepsjon.
For en bedre arbeidserfaring anbefales det fullstendige alternativet. For installasjon på enheter som kun skal brukes til å kjøre noder, er ase-versjonen tilstrekkelig. Men uansett hvilket alternativ du velger, kan du installere hvilken som helst pakke du trenger kalt package_name
når du utfører:
sudo apt-get install ros-indigo-
Understreker erstattes av bindestreker i det endelige navnet, så stage_ros
det vil være i pakken som ros-indigo-stage-ros
.
Neste trinn er å starte rosdep
. Pakker i ROS kan erklære hvilke komponenter de er avhengige av. rosdep
lar deg kompilere disse pakkene uten å stole sterkt på manuell håndtering. For å starte det, ring:
sudo rosdep init rosdep update
ROS har mange miljøvariabler som brukes av verktøyene sine. Med standardinstallasjonen, skriptet bash for å starte dem ligger den i /opt/ros/indigo/setup.bash
. Variabler må startes innen hver økt bash , så den beste løsningen er å legge dem til ~/.bashrc
.
echo 'source /opt/ros/indigo/setup.bash' >> ~/.bashrc source ~/.bashrc
Noen pakker installerer eksterne avhengigheter via rosinstall
, som er tilgjengelig som en pakke og installeres via sudo apt-get install python-rosinstall
Dette er slutten på Ubuntu-installasjonen. Det som følger er en kort introduksjon til oppsett av arbeidsområdet.
Siden Groovy Galapagos , ROS-arbeidsområder er administrert gjennom catkin
. Vi må definere en katalog for alle pakkene vi er vert for. Inne i katalogen oppretter vi en mappe src
og vi kaller catkin_init_workspace
fra innsiden. Det vil skape flere symbolske lenker i den nåværende kildeversjonen av ROS. Neste trinn er å også legge til dette arbeidsområdet i miljøvariablene.
For å utføre alle disse arbeidsinnstillingene, velg en tom katalog og kjør følgende kommandoer:
mkdir src cd src catkin_init_workspace cd .. catkin_make echo 'source $(pwd)/devel/setup.bash' >> ~/.bashrc source ~/.bashrc
Du har nå opprettet et arbeidsområde der du kan lage dine egne ROS-pakker.
Å lage en hvilken som helst kode er et stort sprang. La oss først bli kjent med noen av systemene som kjører bak kulissene. Vårt første skritt vil være å kjøre den grunnleggende GUI og se hvilke meldinger den genererer.
For å kjøre noe i ROS, må du starte en hovedprosess. Det er like enkelt som å åpne et nytt terminalvindu og skrive:
roscore
Over hele det tilkoblede enhetsnettverket, roscore
den trenger bare å utføres en gang på enheten som er vert for det sentrale navet for å sende kommunikasjon.
Hovedrollen til roscore
det vil si å fortelle nodene som andre noder skal koble til, og på hvilken måte (enten via nettverksport eller delt minne). Målet er å la noder bare bekymre seg for hvilke data de vil vite, i stedet for hvilken node de vil koble til, mens du minimerer tiden eller båndbredden de trenger for å utføre all kommunikasjon.
Etter å ha kjørt roscore
, kan vi starte hovedgrensesnittverktøyet for ROS: rqt
. Det vi ser er veldig skuffende - et tomt vindu. rqt
Det er vert for et bredt utvalg av plugins som kan konfigureres i hvilken som helst visuell konfigurasjon og et hvilket som helst antall forhåndsdefinerte visninger.
For å starte kjører vi plugin Robotstyring , velge den i Plugins > Robot Tools > Robot Steering
. Det vi får er to glidebrytere, som representerer den lineære og rotasjonsbevegelsen som vi ønsker at roboten vår skal ha. Øverst på pluginet ser vi en tekstboks med /cmd_vel
i henne. Vi kan gi det et annet navn. Representerer navnet på emnet som publikasjonen er rettet mot. Terminalverktøy er det beste stedet å se hva som skjer i bakgrunnen.
ROS har flere kraftige verktøy for å inspisere hva som skjer i systemet. Det første verktøyet vi skal introdusere er rostopic
, det lar oss inspisere emner som noder kan abonnere på og publisere. Kjør rostopic list
gi til:
/cmd_vel /rosout /rosout_agg
De to siste emnene kjører alltid og er relatert til kjerne-ROS-systemer. Temaet /cmd_vel
blir publisert av adressene våre. Ved å gi nytt navn til emnet i adressene, vil det også gi nytt navn. Nå er vi interessert i hva som skjer innenfor faget. Kjør rostopic echo /cmd_vel
det viser oss ingenting (med mindre du spiller med glidebryterne). Prosessen kjører til vi avbryter den. La oss nå flytte den vertikale glidebryteren på 20 m / s. Når vi ser på ekkoet, kan vi se følgende gjentas igjen og igjen:
linear: x: 0.2 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.0
Hvor ofte spam denne meldingen? rostopic hz /cmd_vel
det står med en gjennomsnittlig hastighet på 10Hz. Vel, hvor mange sanger som dette kan jeg kjøre på min sakte Wi-Fi-forbindelse? rostopic bw /cmd_vel
oppdager i gjennomsnitt 480 B / s.
Det er veldig bra, men vi snakker om meldingstyper. Disse dataene er bra for et menneske, men et program vil trenge rådataene og må kjenne meldingstypen for å tolke dataene. Meldingstypen kan tolkes med rostopic type /cmd_vel
, og fortelle oss at det er en geometry_msgs/Twist
. Alle ROS-terminalverktøy som kalles uten argumenter, returnerer en standard hjelpemelding.
ROS Wiki er bra for å gjøre et websøk etter dette strengresultatet, på en Wiki-forklaring på hva den inneholder og hvordan den er strukturert. Men vi trenger ikke å stole på ham. rosmsg
er det generelle verktøyet for meldingstyper. Kjør rosmsg show geometry_msgs/Twist
komme tilbake:
geometry_msgs/Vector3 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z
Meldingen består av to 3D-vektorer som representerer lineær og vinkelhastighet i 3D-rommet.
Hvis du vil vite hvilke emner en node knytter seg til, rosnode info
Det vil gi oss detaljerte data om noden. Verktøyene rostopic
, rosmsg
og rosnode
er de viktigste verktøyene for å inspisere upolert ROS-funksjonalitet. ROS har mye mer GUI og terminalverktøy, men de er utenfor omfanget i denne introduksjonen.
Hovedverktøyene for å kjøre ROS-noden er rusrun
og roslaunch
. rosrun
du kan utføre noder via rosrun
, og roslaunch
den kjører noder basert på lanseringsfiler, som vi blir lite kjent med, da de er det mest komplekse elementet i ROS-automatisering.
Vi kan stenge alt vi kjører for å begynne å jobbe med vår første kode. For fremtidig referanse vil det være åpenbart at å kjøre alt relatert til ROS krever en aktiv forekomst av roscore
. Mange av problemene du støter på kan løses ved å lukke terminalvinduet som kjører roscore
og åpne en ny for å starte den på nytt. Dette oppdaterer alle avhengighetene som måtte lastes inn på nytt, både i bash
og i roscore
.
Vårt første mål er å etterligne funksjonaliteten til Robot Steering
opprette en node som publiserer data fra geometry_msgs/Twist
a /cmd_vel
basert på en gamepad-inngang. Vår første stopp er pakken joy
.
joy
Pakken joy
gir generiske ROS-drivere for styrespak og gamepads. Den er ikke inkludert i standardinstallasjonen, så den må installeres via:
sudo apt-get install ros-indigo-joy
Etter installasjon kan vi kjøre rosrun joy joy_node
. Dette vil som standard koble oss til styrespaken eller gamepaden. Kjør rostopic list
viser oss at vi har et emne som heter /joy
. Lytt via rostopic echo
Det viser oss meldinger i følgende format (merk at du må samhandle med spillkontrollen eller styrespaken for at meldingene skal publiseres).
header: seq: 4156 stamp: secs: 1450707466 nsecs: 204517084 frame_id: '' axes: [0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0] buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Du kan ignorere topptekstene for nå. Bortsett fra det har vi axes
og buttons
, som pent forklarer hva de representerer. Ved å flytte økser og skyv på knappene i kontrolleren, vil det resultere i at disse tallene endres. Ved å bruke verktøyene våre kan vi bestemme at meldingstypen er sensor_msgs/Joy
og formatet er:
std_msgs/Header header uint32 seq time stamp string frame_id float32[] axes int32[] buttons
Det første trinnet i å skrive kode er å lage en pakke. Inne i mappen src
fra arbeidsområdet, kjør:
catkin_create_pkg toptal_tutorial rospy joy geometry_msgs sensor_msgs
Her oppgir vi navnet på pakken vi lager, etterfulgt av pakker som vi planlegger å være avhengige av. Ikke bekymre deg, avhengighetene kan oppdateres manuelt senere.
Nå har vi en mappe toptal_tutorial
. Inne i mappen, opprett en mappe som heter scripts
som inneholder alle våre Python-skript.
La oss lage en fil som heter teleop.py
, og inne i den vil vi ha:
#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy def joy_callback(data): print data def main(): rospy.init_node('teleop') rospy.Subscriber('joy', Joy, joy_callback) while not rospy.is_shutdown(): pass if __name__ == '__main__': main()
Vi må også angi chmod +x teleop.py
dermed er skriptet kjørbart. Kjør rosrun joy joy_node
i en terminal og rosrun toptal_tutorial teleop.py
i en annen vil det føre til at terminalutgangen teleop.py
blir fylt med meldinger Glede .
La oss undersøke hva koden gjør.
Først importerer vi rospy , som er vert for biblioteket for å samhandle med ROS-rammeverket. Hver pakke som definerer meldinger har en underpakke msg
med meldingsdefinisjoner. Vi importerer Joy
for å håndtere innspill. Det er ikke nødvendig å importere innebygde meldingstyper (som Header
fra std_msgs.msg
som er i meldingen Joy
) med mindre vi ønsker å nevne dem spesifikt.
Vårt første skritt er å initialisere en node med et bestemt navn (i dette tilfellet kaller vi det 'teleop'). Etter det oppretter vi en abonnent som abonnerer på emnetypen 'glede' sensor_msgs.msg.Joy
, og som håndterer hver melding ved å ringe til funksjonen joy_callback
. Tilbakekallingene mottar en parameter, meldingsdataene. Å få tilgang til datamedlemmer er enkelt. Hvis vi ønsket å skrive ut tilstanden til den første akser , hvis vi husker meldingstypen, vil vi ringe print data.axes[0]
, og det vil være en flottør. Knuten på slutten av knop, til ROS slukker.
Vårt neste skritt ville være å administrere dataene våre på en eller annen måte. Vi burde lage en melding Vri som endres, avhengig av innspill, og da vil vi publisere det i emnet cmd_vel
.
#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist # new from functools import partial # new def joy_callback(pub, data): # modified cmd_vel = Twist() # new cmd_vel.linear.x = data.axes[1] # new cmd_vel.angular.z = data.axes[0] # new pub.publish(cmd_vel) # new def main(): rospy.init_node('teleop') pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) # new rospy.Subscriber('joy', Joy, partial(joy_callback, pub)) # modified while not rospy.is_shutdown(): pass if __name__ == '__main__': main()
Først legger vi til meldingen Twist
, og legger til støtte for funksjonelle argumenter med bindinger via functools.partial
. Vi oppretter en annonsør, pub
, som publiserer til cmd_vel
en meldingstype Twist
. Vi knytter den annonsøren til tilbakeringingen og får ham til å sende en melding Vri i hver oppføring med hastighetene representert av de to første økser . Denne koden gjør det som forventes av den, og vi kan se den resulterende effekten via rostopic echo /cmd_vel
.
Vi har fortsatt et problem. Temaet /joy
kan legge ut store hastigheter. Hvis vi overvåker rostopic hz /cmd_vel
og vi flytter den analoge pinnen i sirkler, vi kan se mange meldinger. Dette vil ikke bare resultere i et stort antall kommunikasjoner, men også prosessene som mottar disse meldingene må behandle hver enkelt av dem; det er ikke nødvendig å legge ut så mye data så ofte, og faktisk er det bedre å legge ut med en stabil 10Hz-hastighet. Vi kan få dette med følgende kode.
#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist from functools import partial def joy_callback(cmd_vel, data): # modified cmd_vel.linear.x = data.axes[1] cmd_vel.angular.z = data.axes[0] # moved pub.publish(cmd_vel) to main loop def main(): rospy.init_node('teleop') cmd_vel = Twist() # new pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) rospy.Subscriber('joy', Joy, partial(joy_callback, cmd_vel)) # modified rate = rospy.Rate(10) # new while not rospy.is_shutdown(): pub.publish(cmd_vel) # new rate.sleep() # new if __name__ == '__main__': main()
Vi endrer tilbakeringingen for å motta det mutable objektet Twist
og modifiser den inne i løkken. Funksjonen sleep
av rospy.Rate
opprettholder en stabil utgangsfrekvens.
Den endelige koden vil resultere i emnet /cmd_vel
oppnå kommandohastigheter på 10 Hz, og dermed etterligne plugin-utgangen Robotstyring rqt
Vårt første mål er å skape et miljø der vi kan simulere scenariet vi ønsker å oppnå. Noden stageros
inne i pakken stage_ros
Det vil tillate oss å utføre en robot i et 2D-trinn definert av et bilde. Det er en hel syntese beskrevet i pakke stage_ros
for verdensarkiver og hvordan man kan generere dem. Dette er ganske greit, men utenfor rekkevidde. Heldigvis kommer pakken med flere verdensdemoer. La oss først gå til filkatalogen ved kjøring:
roscd stage_ros cd world
Inne i mappen er det flere filer. La oss kjøre en.
rosrun stage_ros stageros willow-erratic.world
Ulike temaer ble opprettet. Betydningen av hver av dem er også dokumentert med pakken. Det viktige er at den har cmd_vel
.
Inne på scenen som vises er det en blå boks, dette representerer roboten du styrer. Ved å bruke koden vår eller Robotstyring vi kan kontrollere denne roboten. Prøv det!
Først oppretter vi en mappe launch
eller lanzamiento
inne i pakken og inne i den, opprett en fil som heter teleop.launch
. Den endelige strukturen til mappen skal se slik ut:
toptal_tutorial/ ├── CMakeLists.txt ├── launch │ └── teleop.launch ├── package.xml ├── scripts │ └── teleop.py └── src
Inne i filen teleop.launch
Vi vil definere flere noder og deres sammenkoblinger.
robot_
Den nye verden består av fire roboter, og hvert av temaene har et prefiks kalt robot_0/cmd_vel
. Dermed har robot nummer 0 et kommandohastighetstema kalt robot_0
. Dette er grunnen til at vi setter kontrollen vår i navneområdet med navnet roscore
og så vil vi tilpasse navnene til det nye skjemaet. På denne måten kan du tenke på emnenavn som mapper i et filsystem.
Du trenger ikke roscore
for å kjøre startfiler. På en måte roscore
det er bare et spesielt tilfelle av en lanseringsfil som ikke gjør noe. Hvis en roslaunch toptal_tutorial teleop.launch
bare den første lanserte lanseringsfilen vil kjøre en kjerne, mens resten vil koble til den. Nå skal vi utføre lanseringen med:
/robot_/base_pose_ground_truth /robot_/base_scan_0 /robot_/base_scan_1 /robot_/camera_info_0 /robot_/camera_info_1 /robot_/cmd_vel /robot_/depth_0 /robot_/depth_1 /robot_/image_0 /robot_/image_1 /robot_/odom
Hvis alt er i orden, vil dette resultere i en simulator med 4 roboter, hvor hver og en styres med gamepad eller styrespak. Denne verden har mye mer innhold enn den forrige. Hver av de fire robotene har følgende:
rqt
Vi erstatter med 0, 1, 2 eller 3. Og med dette kommer vi til vårt siste emne.
rqt
Tidligere har vi ikke fordypet oss i image_0
men det er det perfekte verktøyet for å visualisere mer komplekse data. Du kan eksperimentere med alle temaer, men vi vil fokusere på image_1
, depth_0
, depth_1
og rqt
temaer.
Løping Plugins > Visualización > Vista Imagen
vi fjerner alle åpne plugins. Nå åpner vi 4 bildevisere (robot_0
) og legger dem i et 2x2-rutenett. Til slutt, i øvre venstre hjørne av hver av visningene, velger vi ett av de fire temaene som er etablert for stage_ros/world
.
Det vi får er dyp oppfatning stereosyn med kameraer med lav oppløsning. Merk at vi kunne ha oppnådd dette resultatet uten vårt inngangssystem. Hvis vi bare kjører dette (fra mappen rosrun stage_ros stageros willow-four-erratics-multisensor.world
):
/robot_0/cmd_vel
Og vi legger til pluginet Robotstyring med et emne som heter export ROS_MASTER_URI=http://:11311/
Vi kunne ha hatt det samme resultatet hvis kontrollene var på skjermen.
Mange maskinvarer støtter ROS fullt ut, ofte takket være tredjeparter. Mange robotplattformer har drivere som genererer denne typen meldinger, og ROS har noder som aktiverer webkameraet og publiserer en feed av bilder.
Mens det siste resultatet var en simulering av hva vi ønsker å oppnå; det samme kan oppnås med følgende modifikasjoner:
rqt
på den eksterne datamaskinen når du starter i Bash, så vil den eksterne datamaskinen se på verten og portengazebo
og / eller et hvilket som helst skript for å overvåke og kontrollere robotenTil slutt skal bare passende variabelt miljø eksporteres på den eksterne enheten, og alt annet gjøres av seg selv. Å kjøre ROS på en dataklynge tar bare ett trinn for å gjøre seg klar på hver maskin.
Vi har vist hvordan du med hver kode, uansett hvor liten, kan ha et komplekst system med variabler som du kan manipulere uansett hvordan du vil. Det enkle utgiver- / abonnentsystemet muliggjør rask programvareutvikling som behandler data på en klynge datamaskiner, samtidig som du gir deg sjelefred så du ikke trenger å bekymre deg for den underliggende implementeringen av visse elementer.
Mens vi bruker en enkel simulator, andre mer komplekse simulatorer som
|_+_|(som er inkludert i den fullstendige stasjonære versjonen) kan du opprette 3D-verdener med komplekse fysiske sensorer Og det gir deg en opplevelse av sluttresultatene og produktet før det utvikles.
Denne introduksjonen var noe grunnleggende, men det er håpet du vil føle deg mer interessert i å jobbe med dette allsidige rammeverket.