Menu Zavřít

Roboti na nošení léků, jídla i piva. Autonomní vozítka z české dílny Vanilla Robotics umí mapovat prostor

12. 11. 2021
Autor: Lukáš Bíba
  • Český startup Vanilla Robotics uspěl v akcelerátoru Josefa Průši

  • Během půl roku se jeho zakladatelům podařilo vytvořit autonomní roboty, kteří se pohybují na základě senzorů a umělé inteligence

  • Slouží k roznášení věcí – od potravin po léky. K základní verzi stroje se má v budoucnu přidat velké autonomní vozidlo


„Každý by najradšej ležal pekne na lehátku, doma na lehátku. Veď na čo by aj behal, keď všecko je v porádku, doma na porádku,“ zpívá slovenská kapela Horkýže slíže ve slavném hitu. Tomáš Krivda ze startupu Vanilla Robotics sdílí se zpěvákem Petrem Hrivňákem nejen národnost, ale i touhu nerušeně ležet na gauči a nemuset chodit do lednice kvůli dalšímu orosenému pivu.

„Do PrusaLabu jsme se přihlásili s trochu šíleným nápadem,“ přiznává. „Naše hlavní myšlenka byla, že vytvoříme robota, na kterém seshora otevřete poklop a dáte si tam pivo. Lehnete si na gauč a on Vám bude nosit lahváče,“ vysvětluje Krivda s úsměvem. Jakkoli svůj vlastní nápad označuje za velmi netradiční, Josefa Průšu zaujal natolik, že se rozhodl ho podpořit v ročním akcelerátoru jako jeden ze tří inovativních projektů.

Josef Průša investuje miliony do firmy ze svého akcelerátoru. Startup Posedla učí lidi jezdit na kole
Přečtěte si také:

Josef Průša investuje miliony do firmy ze svého akcelerátoru. Startup Posedla učí lidi jezdit na kole

Zakladatelé značky Vanilla Robotics dokázali během šesti měsíců ve spolupráci s PrusaLab vyvinout autonomní robotická vozítka, která konkurují logistice doručovacích služeb i velkých skladišť. Připomínají malý kontejner, ale uvezou až 25 kilogramů nákladu a na jedno nabití vydrží jezdit asi deset hodin, což s přestávkami může vystačit i na jeden celý den.

Mapování prostoru

Tím nákladem mohou být například zmíněné pivní plechovky a lahve, ale i potraviny nebo jiné předměty dle potřeby. „Ve Slezské nemocnici v Opavě si roboti vyzkoušeli nošení prádla, léků a dalších věcí,“ vypráví druhý společník firmy Jan Sedláček. Stroje se za pomoci umělé inteligence a zabudovaných kamer či senzorů umí pohybovat ve známém prostoru samy. Rozpoznávají překážky a lidi, kteří jim stojí v cestě, a v reálném čase se učí mapovat okolní prostředí. Vývojáři to ilustrují na příkladu toho, že nechávali roboty volně jezdit po dílnách PrusaLabu, vždy asi na 30 nebo 40 minut. Vozítkům se podařilo postupně zorientovat se v prostředí a vytvořit si jeho mapu. Teď už se tam pohybují bez zaškobrtnutí. Stejně se to naučí i v jakékoli domácnosti.

Navíc pokud člověk chce, může ovládat svého robota přes aplikaci pro iPad nebo Mac. K počítači se připojí joystick a na obrazovce se ukáže, co robot „vidí“ před sebou. Pak ho člověk může jakkoli nasměrovat. Dokonce je prý možné i operovat s několika roboty současně a přepínat mezi jejich pohledy.

Vozítko od Vanilla Robotics má v horní části schránku na náklad. Uveze až 25 kilo. Foto: Vanilla Robotics

Vanilla Robotics vytvořili platformu, kombinující hardware i software, která umožňuje provoz těchto autonomních robotů. Postupně během vývoje však vzniklo platforem několik. V prototypu figuruje zatím jen jedna. „Od malé platformy se chceme odrazit dál. Prodejem hardwaru a softwaru z malé platformy vyděláme peníze na další platformy. Další stupeň našeho vývoje bude velké vozidlo,“ říká Krivda. První roboti se v praxi přitom mají objevit na pražských ulicích příští rok.

„Nespornou výhodou se pro nás stalo technologické zázemí PrusaLabu, kde jsme mohli nejen díky 3D tisku prototypovat a testovat různé varianty našeho řešení — vše na jednom místě, za pomoci expertů, a daleko rychleji a levněji než předtím. Ačkoliv byl projekt nejdříve víkendovou záležitostí, účast v akcelerátoru nám umožnila pustit se do intenzivního vývoje,“ komentuje Sedláček. Odborníci na 3D tisk asistovali i u designu a tvorby softwaru. Kromě PrusaLabu však vývojářům pomáhalo i několik univerzit. Japonský profesor jim radil ohledně senzorů a strojového „vnímání“. ČVUT zase umožnila první testy prototypů v Děčíně.

Pomocníci kurýrů

Robotičtí kurýři však už dnes přestávají být unikátem. Logistika během pandemie musela zásadně posílit, a tak lidští šoféři a skladníci začali být vytížení až příliš. V expedičních depech Zásilkovny už pomáhají třídit balíky robotická vozítka PackMan, která je dopravují na příslušné místo určené kód. Simona Kijonková si je nemůže vynachválit, údajně pracují dvakrát efektivněji než lidé.

Pandemie urychluje nástup donáškových robotů, k vidění jsou od Kalifornie po Estonsko
Přečtěte si také:

Pandemie urychluje nástup donáškových robotů, k vidění jsou od Kalifornie po Estonsko

Další donáškoví roboti jsou k vidění v různých zemích po celém světě. Často je využívají například restaurace k donášení jídla. Zákazníci, kteří si objednají svou porci domů, mívají totiž často takový strach z nákazy, že dají přednost bezkontaktnímu doručení robotem. Estonská firma Starship Technologies na robotických kurýrech pracuje už dva roky a dnes jich má v týmu už více než tisíc. Pohybují se rychlostí osm kilometrů v hodině a kvůli nutnosti častého nabíjení mají relativně malou dojezdovou vzdálenost.

WT100_25

Také je fér přiznat, že na ulicích velkých měst by je lidé nejspíš ušlapali nebo rozkopali. Proto operují jinde – v kampusech univerzit a v byznys parcích. Zaneprázdněným manažerům nebo vědcům roboti pravidelně vozí obědy, což ulevuje vytíženým kurýrům restaurací. Jeden estonský robot zatím vyjde na 110 tisíc korun. Cenu českých vozítek od Vanilla Robotics zatím neznáme, ale využití u nás rozhodně najdou – ať už budou pendlovat mezi lednicí a gaučem, nebo nosit léky do nemocničních pokojů.

  • Našli jste v článku chybu?
'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }