czech english

Kayeton

USB Camera with Fisheye Lens

USB kamera na SubT Challenge.

Zbyněk 6/5

Dodací lhůta je cca 27 dní. Tj. včera bylo pozdě (na objednání). Tak zvažuji 2 nebo 4 kamery? Rovnou fisheye nebo k nim mám přibrat i nějaké jiné objektivy? Hmm. Předběžně uvažuji jen fisheye a 4ks - tj. 4x https://www.aliexpress.com/item/Global-Shutter-High-Speed-120fps-Webcam-UVC-Plug-Play-Driverless-USB-Camera-Module-with-Fisheye-Wide/32944337155.html?spm=a2g0s.8937460.0.0.414e2e0eZ1GatU — fisheye proto, že přicházím "jen" o rozlišení (dá se transformovat na "normální" kameru) a 4 ks protože dlouhá dodací lhůta.

Freyja

Jirka 18/5

Kamery dorazily.
  • Prvni, kterou jsem zkusil, funguje. Chova se jako poctiva UVC kamera, takze u me 0 noveho kodu. Plug & play. Az na to, ze ten obraz mozna budu chtit narovnat.
  • Opravdu posila 120 FPS.
  • Tech 180 stupnu FOV ma bud horizontalne, nebo diagonalne. Rozhodne ne vertikalne. Tohle jsem asi mel vzhledem k obdelnikovemu obrazu cekat.
  • Ve tme se chova webcam na mem notebooku lepe. Po nasviceni baterkou to ale vypada nadejne (= zelena je zelena, tmave modra je tmave modra, sum nevidim).
  • V rozich je trosku cerno. Ne moc. Neni to jako drivejsi rybooka kamera na Eduru, kde byl obrazek jen v kruhu uprostred a pulka obrazu bylo cerno.
Mala neprijemnost (aspon pro me): Diry na srouby v rohu maji prumer 2 mm nebo kolik. Tolik tak malych sroubu nemam a nase Bau & Hobby je nevede :-/

PavelS 3/6

V priloze jsou STL a obrazky krabicky na kamerku: KytBox1.STL, KytBox2.STL. Kvuli otvorum se krabicka smontuje pomoci sroubu M2 a za usi se da pripevnit srouby M3 nebo pomoci stahovaci pasky. Ja si budu jeste tisknout doplnek pro montaz na profily 20x20 mm na Robika.

Jirka 7/6

Myslim, ze Zbynek zminoval, ze mu to nedava deklarovanych 120 FPS.
Ja jsem psal, ze mi to funguje. To bylo na notebooku. Na robotovi se z nejakeho duvodu prepnou do 30 FPS. V jednom pripade dokonce na 16 FPS. Coz jsou hodnoty, ktere ta kamera ani nedeklaruje jako podporovane :-O `v4l2-ctl -p 120` je hodi tam, kde maji byt. Jeste jsem nezkousel, jestli to prezije restart. Jestli ne, melo by to jit nastavit i z kodu.

VIDIOC_STREAMON: No space left on device

Zbyněk 4/6

Snažím se nějak rozchodit https://github.com/pupil-labs/pyuvc.
Je tam pár gotchas. Například pyuvc je cython wrapper na libuvc, ale ne nad original, ale nad jejich fork zde https://github.com/pupil-labs/pyuvc/. Jejich fork je trochu upravený - například nepoužívají jiný transport než mjpeg, tj. plain yuv (i když ho kamera umí) se touto cestou získat nedá.
Takže pro notebookovou kameru mi to už funguje. Pro tu Kayeton ještě ne.
$ v4l2-ctl -d 1 –list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Index       : 0
Type        : Video Capture
Pixel Format: 'MJPG' (compressed)
Name        : Motion-JPEG
Size: Discrete 1280x720
Interval: Discrete 0.008s (120.000 fps)
Tento jeden mód to podporuje, ale nedaří se mi pyucv říct, aby ho použil. Asi někde něco nastavuje jinak, protože když to zkusím, tak mi hlásí:
DEBUG:uvc:Setting mode: 1280,720,120
Can't start isochronous stream: Error:'Mode not supported.'.
Tj. v debug výspupu píše, že ḿód nastavil ok, ale když chci streamovat, tak najednou mód ok není :-(.
Zkoumáním zdrojáků libucv (jejich forku) jsem zjistil, že tam přidali nějaký bandwitth_factor. To je asi něco na rezervování usb kapacity. Nakonec se mi podařilo vyexperimentovat, že je třeba ho z defaultní hodnoty 2 změnit na 1.5 - a běží! A dokonce tam ani není žádný lag. Když to zobrazuji pomocí opencv, dostávám 85 až 93Hz. Když to nezobrazuji, dostávám se k 95Hz. Tady tipuji, že jsme na hranici pythonu, protože na podobné frekvenci běží všechno, co máme, když tam nedáme sleep.

Po docela náročném boji se vším možným mi nyní běží example.py pro pyuvc na robikovi. Říká, že dělá 96Hz - tj. stejně, jako na notebooku. Taky jsem zvědav, jak se to bude chovat v případě, že tam těch kamer budeme mít připojeno více než jednu. Zdá se, že kamery nemají žádné sériové číslo, kterým by se daly od sebe rozlišit.
{'bus_number': 3,
  'device_address': 6,
  'idProduct': 5461,
  'idVendor': 5546,
  'manufacturer': 'RYS HFR USB2.0 Camera',
  'name': 'RYS HFR USB2.0 Camera',
  'serialNumber': 'unknown',
  'uid': '3:6'}
btw: http://wiki.ros.org/libuvc_camera kdyby to chtěl někdo připojit rovnou pod ROS

Jirka 4/6

Potvrzuju nedostatek serial id. Nicmene reseni existuje.
Na linuxu se da pristupovat k zarizeni na usb podle mista jeho fyzickeho pripojeni. A to bud pomoci uz existujicich symlinku v /dev/v4l/by-path/, nebo si pomoci udev pravidel vytvorit symlinky vlastni.
U me, pri kamerach na usb hubu, mi to vychazi takhle:
SUBSYSTEM"video4linux",KERNELS"2-2.2:1.0",SUBSYSTEMS"usb",DRIVERS"uvcvideo",ATTR{index}"0",SYMLINK+="camera_green"
SUBSYSTEM"video4linux",KERNELS"2-2.3:1.0",SUBSYSTEMS"usb",DRIVERS"uvcvideo",ATTR{index}"0",SYMLINK+="camera_blue"
SUBSYSTEM"video4linux",KERNELS"2-2.6:1.0",SUBSYSTEMS"usb",DRIVERS"uvcvideo",ATTR{index}"0",SYMLINK+="camera_yellow"
SUBSYSTEM"video4linux",KERNELS"2-2.7:1.0",SUBSYSTEMS"usb",DRIVERS"uvcvideo",ATTR{index}"0",SYMLINK+="camera_red"
Po 'sudo udevadm control –reload-rules' pak vidim /dev/camera_green apod. "guvcview -d /dev/camera_green" funguje. Jak presvedcit libuvc k pouzivani techhle symlinku jeste nevim.
Magicka cisla jsem posbiral z "udevadm info /dev/video2", "ls /dev/v4l/by-path" a "sudo dmesg" po pripojeni hubu. "ATTR{index}" nemusi byt na starsich kernelech potreba. Netusim, jestli tam dokonce nemuze v takovem pripade zavazet.
V libuvc jsem nasel jenom rozlisovani kamer indexem, podobne jako je to v OpenCV. Nevim, odkud se ten index bere, a proto neverim jeho stabilite mezi rebooty. V4L otevira zarizeni identifikovane jeho cestou a s temi symlinky funguje. Tj. ja pujdu tudy a libuvc dal resit nebudu.

"Používá nějaké uid, což je busnumber:devicenumber. Tj přijde mi to stejné.
Busnumber je stabilni, devicenumber zavisi napr. na pritomnosti jinych zarizeni. To jsem vcera zkousel. Kdyz jsem hub odpojil, vyndal z nej neco jineho nez kameru a zapojil zpatky, mely kamery jine devicenumber. Coz by davalo tusit, ze to system prirazuje sekvencne podle poradi inicializace, ne podle cisla usb portu. Ale jisty si nejsem.

ZW:
tak tomu druhému číslu říká device_address. Zkoušel jsem teď kameru do jiných portů a číslo se mění. Bohužel když mám kameru v portu A (device_address 11) a dám do portu B (device_address 12) a pak zpět do portu A, dostanu device_address 13 :-(
Tak jsem se chtěl podívat na v4l, ale… Mám pouze /dev/video0 a tam je notebooková kamera. Puvc stále ukazuje kamery dvě, nicméně ta kayeton nejde otevřít :-(. Aha, tak je to takhle: Po zastrčení kamery do usb se objeví i /dev/video1. Spustím-li svůj libuvc example, tak selže a navíc /dev/video1 zmizí. Pustím-li místo toho guvcview -d /dev/video1, tak to funguje :-(.

JI:
  • Misto xioctl mozna dava lepsi smysl v4l2_ioctl.
  • Format je asi mozne takhle natvrdo nastavit. Ale existuje i funkce, ktera vrati seznam podporovanych formatu a pak jde nastavit jeden z nich. Nastavovani neexistujicich formatu je, myslim, jeden z okamziku, kdy se uvcvideo chova nestabilne.
  • Tenhle priklad alokuje jediny buffer na prichozi obrazky. A pak do nej zaroven streamuje a zaroven ho zpracovava. To se mi moc nezamlouva. Rozhodne ne pri 120 FPS. Vic bufferu, vic adidas.
  • Nat tim selectem v kroku 6 se musim zamyslet. Prijde mi zbytecny. Podle me VIDIOC_DQBUF blokuje, dokud neprecte aspon nejaka data. Asi jako read().
  • Podobne jako read(), VIDIOC_DQBUF nemusi na jeden zatah ziskat vsechna data. Je potreba cist jeho navratovou hodnotu a pripadne ho zavolat znovu. aspon tak jsem pochopil dokumentaci ja.
Mimochodem, dokumentaci k v4l povazuju za jednu z tech lepsich, co jsem kdy cetl: https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/v4l2.html
Da se postupovat podle ni kapitolu po kapitole a ten kod podle toho napsat.

ZW:
device number je opravdu nestabilní, ale důvod, proč se používá, je asi ten, že těch portů může být cestou víc. Našel jsem https://stackoverflow.com/questions/14279796/linux-libusb-get-usb-device-path http://libusb.sourceforge.net/api-1.0/group__dev.html#gaa4b7b2b50a9ce2aa396b0af2b979544d
int libusb_get_port_numbers 	( 	libusb_device *  	dev,

	
	uint8_t *  	port_numbers,

	
	int  	port_numbers_len 

	)
Tak jsem si s tím trochu pohrál a mám následující:
dev_list = uvc.device_list()
    pprint(dev_list)
vrací
[{'bus_number': 1,
  'bus_ports': bytearray(b'\x05'),
  'device_address': 2,
  'idProduct': 22049,
  'idVendor': 3034,
  'manufacturer': 'KS0HD05012839056B6LM03',
  'namee': 'HD WebCam',
  'serialNumber': '200901010001',
  'uid': '1:2'},
 {'bus_number': 1,
  'bus_ports': bytearray(b'\x03'),
  'device_address': 12,
  'idProduct': 5461,
  'idVendor': 5546,
  'manufacturer': 'RYS HFR USB2.0 Camera',
  'namee': 'RYS HFR USB2.0 Camera',
  'serialNumber': 'unknown',
  'uid': '1:12'}]
Za povšimnutí stojí bus_ports, kde je kompletní strom odpovídající lsusb -t toho, přes jaké porty na všech hubech cestou je kamera připojená.
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/8p, 10000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M
    |__ Port 3: Dev 12, If 0, Class=Video, Driver=uvcvideo, 480M
    |__ Port 3: Dev 12, If 1, Class=Video, Driver=, 480M
    |__ Port 5: Dev 2, If 1, Class=Video, Driver=uvcvideo, 480M
    |__ Port 5: Dev 2, If 0, Class=Video, Driver=uvcvideo, 480M
    |__ Port 14: Dev 3, If 0, Class=Wireless, Driver=btusb, 12M
    |__ Port 14: Dev 3, If 1, Class=Wireless, Driver=btusb, 12M
Tj. libucv by mělo jít použít, protože kamery od sebe dokážu rozlišit. Nakonec mně to přišlo jednodušší než se učit v4l2.
V rámci archivace Jirkův link pro "no space left on device" při více kamerách: http://www.ideasonboard.org/uvc/faq/

libuvc + pyuvc

zw 14/7

Tak první kroky jsou zde:
  • https://github.com/zwn/libuvc je repozitory, kde je aktualizované libuvc; to je třeba stáhnout a zbuildovat - už by tam mělo být originál repozitory z pupil-labs, tj. mělo by stačit přidat nový remote a stáhnout tam jeden nový commit a dát "make install" v build adresáři.
  • https://github.com/zwn/pyuvc je aktualizované pyuvc; platí pro něj to samé jen s tím rozdílem, že kompilace a instalace se dělá pomocí python setup.py install (už si nepamatuji, jestli je na robikovi virtualenv)
Dependence už by tam měly být nainstalované a kompilace by měla proběhnout bez problémů.
Pak by mělo fungovat
from pprint import pprint
import uvc
dev_list = uvc.device_list()
pprint(dev_list)
a výsledkem by mělo být něco jako tohle:
[{'bus_number': 1,
  'bus_ports': [5],
  'device_address': 2,
  'idProduct': 22049,
  'idVendor': 3034,
  'manufacturer': 'KS0HD05012839056B6LM03',
  'namee': 'HD WebCam',
  'serialNumber': '200901010001',
  'uid': '1:2'}]
Klíčová je položka "bus_ports", což je cesta přes všechny usb huby a čísla portů. Tím se jednoznačně identifikuje usb port a je tak možné rozlišit dvě totožné kamery (bez seriového čísla).
Výše uvedené by mělo fungovat na jakémkoli systému - tj. snad dokonce i na windows, ale nezkoušel jsem to (co si pamatuji, tak je třeba ještě libusb a turbojpeg).
Následně už je potřeba jen update osgara, který děláme standardní cestou. Tak ten připravím do PR (přehodit původní kameru na tohle + přidat kayeton kameru). Kamera v configu nebude identifkovaná indexem, ale právě těmi integery z "bus_ports".

md 19/7

Na Robíkovi byly problémy s libturbojpeg.a:
/usr/lib/gcc/arm-linux-gnueabihf/5/../../../arm-linux-gnueabihf/libturbojpeg.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
kde je potřeba .so dynamická knihovna. Na Zbyňkovo doporučení jsem „schoval” jednu z variant, aby se použila ta správná, lokální:
/usr/lib/arm-linux-gnueabihf/libturbojpeg.a
/usr/local/lib/libturbojpeg.a
/usr/local/lib/libturbojpeg.la
/usr/local/lib/libturbojpeg.so
/usr/local/lib/libturbojpeg.so.0
/usr/local/lib/libturbojpeg.so.0.1.0
Následný python setup.py install prošel a příklad na Robíkovi se dvěma kamerami vypsal:
[{'bus_number': 3,
  'bus_ports': [1, 2],
  'device_address': 4,
  'idProduct': 2085,
  'idVendor': 1133,
  'manufacturer': 'unknown',
  'name': 'unknown',
  'serialNumber': '015AE360',
  'uid': '3:4'},
 {'bus_number': 3,
  'bus_ports': [1, 1, 2, 4],
  'device_address': 8,
  'idProduct': 5461,
  'idVendor': 5546,
  'manufacturer': 'RYS HFR USB2.0 Camera',
  'name': 'RYS HFR USB2.0 Camera',
  'serialNumber': 'unknown',
  'uid': '3:8'}]
V OSGAR masteru je již kód a konfigurace na nahrávání/testování více USB kamer:
python -m osgar.record config/test-usb-camera.json –duration 3
Ale zatím není jisté, co přesně se má použít za port, když kombinace bus 3 a port 2 a 4 selže:
camera not found on bus 3 and port 2
camera not found on bus 3 and port 4