Monthly Archives: January 2011

Limitations of the Kinect

or “Why do we still need other sensors if the Kinect is so awesome?”

The Kinect is a great sensor and a game changer for mobile robotics, but it won’t make every other sensor obsolete. Though maybe I can use it to convince someone to let me take apart a Swiss Ranger 4000.

Field of View

The field of view is an important consideration for sensors because if you can’t see enough features you can’t use scan matching/ICP to estimate your change in position. Imagine if you were in a giant white room with only one wall that was perfectly flat. if you walk along the wall there is no way to determine your movement except from how many steps you take. With a robot you have wheel slip and encoder errors that build up over time unless there are landmarks that can be used to bound the error.

The depth image on the Kinect has a field of view of 57.8°, whereas the Hokuyo lasers have between 240° and 270°, and the Neato XV-11’s LIDAR has a full 360° view.

In addition to being able to view more features, the wider field of view also allows the robot to efficiently build a map without holes. A robot with a narrower field of view will constantly need to maneuver to fill in the missing pieces to build a complete map.

One solution would be to add more Kinects to increase the field of view. The main problem is the sheer volume of data. 640 x 480 x 30fps x (3 bytes of color + 2 bytes of Depth) puts us at close to the maximum speed of the USB bus, at least to the point where you are only going to get good performance with one Kinect per bus. My laptop has two USB buses that have accessible ports, and you might get four separate buses on a desktop. Assuming you down sample until it works computationally you still have to deal with power requirements, unless your robot is powered by a reactor, and possible interference from reflections to deal with.

Another simpler approach is to mount the Kinect on a servo to pan horizontally, this however reduces the robot to intermittent motion where it is constantly stopping and scanning. Depending on your robot’s mechanical design you may be better off rotating the robot.

Range

The minimum range for the Kinect is about 0.6m and the maximum range is somewhere between 4-5m depending on how much error your application can handle. The Hokuyo URG-04LX-UG01 works from 0.06m to 4m with 1% error, and the UTM-30LX works from 0.1m to 60m. The XV-11 LIDAR does 0.2m to 6m. So the Kinect will have the same problems as the more expensive laser range finders in terms of being able to see the end of a long hallway, but the bigger problem will be the Kinect’s close range blind spot. I’m sure it wouldn’t be hard to imagine the dangers of a soft squishy dynamic obstacle approaching a robot from behind, then standing within 0.6m (2ft) while the robot turns and drives forward over the now no longer dynamic obstacle. It can also make maneuvering in confined spaces difficult without a priori knowledge of the environment.

One solution to this would be to add an additional laser projector to the Kinect so that the baseline could be adjustable and the minimum range could be closer. Another approach would be to place the sensor on the robot looking downward at a point high enough to ensure that the dynamic obstacles and their parents were detectable at all times.

The maximum range will be limited by the need to be eye-safe, the power output of the Kinect laser is spread out as a set of points projected over a large surface area, while more traditional 2D laser scanners direct their entire power output to a single point. The 2D laser scanner will generally be capable of a longer range given accurate time-of-flight measurements. The other major limit to the Kinect’s maximum range will be the need to make the Kinect wider to increase the distance between the laser projector and the IR imager to have a large enough baseline.

Environmental

The environmental challenges for the outdoor use of laser scanners has been fairly well studied, with rain and dust being known problems. Changing lighting conditions, from clouds passing overhead, can also wreak havoc with some sensors. I would be interested in seeing experimental results using the Kinect outdoors, during the day, in adverse weather. However, it should work well at night with good weather.

One important question is, can the Kinect see snow?

Computation and Thermodynamics

(updated: 22:28 EST 12/17)

Having designed and built several mobile robots I can safely say that once all the software is debugged, all the electronics are rewired and actually labeled, and the mechanisms are all lubricated, the biggest problem is thermodynamics. Battery technologies are a set of trade-offs that in the end give you some amount of potential energy stored in a constant volume of space, having a constant mass.

The amount of operating time for the robot is limited by how fast you convert that potential energy into kinetic energy or heat. On the electromechanical side you can recover some energy by using regenerative breaking to convert kinetic energy into potential energy and heat. While researchers have made some progress on reversible computing, there is currently no regenerative computing so all of the energy spent computing ends up as heat. So as we add computation power to the robot we are effectively decreasing the operating time.

As the compute power is increased the run time is decreased, so to make up for it you can add more batteries. As you add more batteries the mass of the robot increases, so the motors need more power to accelerate the robot. So to make up for it you can add more batteries.

In terms of testing algorithms and getting research done, offloading computation to a ground station is a valid solution. However, it may not be a practical solution for regular operation since wireless networks may not have complete coverage or reliability.

As you may imagine these problems are worse if your robot is flying. On the upside, cooling the robot is easier.

Results

With a little bit of work the Kinect can provide more than enough sensing capabilities to put your robot into the big leagues, but traditional laser range finders still have a use and at the very least make solving some of the problems easier.

References

This paper has important details on the XV-11 LIDAR
Kinect calibration technical details can be found here.

Submit your ideas or corrections in the comments. Clarifications available upon request.

Linux에 인식된 장치 인식 방법.

참고:
http://www.google.com/search?q=proc_us ··· Bbtni%3D
http://www.linux-usb.org/usb2.html
http://www.usb.org/developers/docs/EH_MR_rev1.pdf
http://www.os2warp.be/index2.php?name=usbreview

/proc/bus/usb/devices 라는 파일은 현재 꽂혀있는 USB 관련 장치들을 보여주는 파일이다.
(/proc 은 가상의 파일 시스템이고 bus 는 말단의 장비들을 꽂을 수 있는 도로와 같은 것이다)

내가 가지고 있는 2002년 정도에 지급받은 PC에서 위 파일 내용을 살펴보면,

$ cat /proc/bus/usb/devicesT: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.17-1.2139_FC4 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1f.4
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.17-1.2139_FC4 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1f.2
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

사실 아무것도 설치되지 않은 상황에서 두 개가 보인다. USB는 하나는 호스트가 되고 하나는 장비가 되어 연결되는 상하관계가 있는 계층 구조를 이루고 있는데, 위 내용의 “S:” 라인을 보면 호스트를 제어하기 위한 “UHCI Host Controller”, 즉, 호스트 컨트롤러가 하나의 장비로 취급되어야한다는 스펙에 의해 보이는 것이다.

맨 윗줄에 나오는 “T:” 는 Topology, 즉 현재 위치를 말해주는데, 첫줄을 풀어서 설명하자면,

T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2

Topology:
버스번호=02
레벨=00
부모장치번호=00
물리적 포트 번호=00
순서(Cnt)=00
장치번호=1
스피드=1.2Mbps
최대꽂을수있는장비개수(child)

위 두 장비의 차이는 버스번호, SerialNumber 인데, 이로써, 서로 다른 값을 가지는 버스가 두 개인 것을 알 수 있다. 그리고 각각은 최대 두개씩 장비를 꽂을 수 있는 것이고, 따라서 4개까지 지원되며 각각의 최대 속도는 12Mbps이다.

현재 USB2.0까지 나온 상황에서 속도는 1.5Mbps (USB1.0), 12Mbps(USB1.1), 480Mbps(USB2.0) 이다. 속도는 Spd 항을 봐서도 알 수 있지만, Product 에 보면 UHCI라고 되어 있는데, 이는 Universal host controller interface라는 것이고, Open host controller interface(OHCI)와 더불어 12Mbps (USB1.1)까지 지원한다. 호스트 컨트롤러의 버전은 “D:” 항 장치 설명에서도 Ver=1.10 으로 확인 할 수 있다.

USB 구성 을 나타내는 “C:” 는 “*”이 하나 붙어 있으며, 이 이하는 USB 를 사용하는 방식에 대한 기술이다. 나중에 다시 설명하기로 하고, 척 보았을 때 “*” 을 기준으로 위까지만 하드웨어적인 것이라 생각해 두자.


요즘 받은 새로운 장비를 한 번 살펴본다.

T: Bus=04 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.2
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.1
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc=118/900 us (13%), #Int= 1, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.0
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 7 Spd=1.5 MxCh= 0
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=055d ProdID=0001 Rev= 1.00
S: Manufacturer=SAMSUNG
S: Product=USB SEM-DT35
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms

T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 6
B: Alloc= 0/800 us ( 0%), #Int= 1, #Iso= 0
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 ehci_hcd
S: Product=EHCI Host Controller
S: SerialNumber=0000:00:1d.7
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=256ms

몇가지 주목할 만한 것이 있는데, 여기에는 키보드가 하나 꽂혀있다.
잘보니 삼성키보임을 알 수 있고, 실제 103키 아주 단순한 키보드가 꽂혀있다.
그리고, 버스가 4개나 되는 것을 보아 상당히 많은 포트를 꽂을 수 있는 머신이다.
버스 중에서 01번은 EHCI(Enhanced Host controller interface) 임을 알 수 있는데, 이것이 USB2.0을 지원하는 포트이다.
버전 설명을 봐도 1.1 -> 2.0 으로 바뀐 것을 알 수 있다.
속도(Spd)도 480Mbps이고 최대 꽂을 수 있는 장비의 수(MxCh)는 6 개나 된다.
상당히 긴 리스트에서 HCI와 일반 장비를 쉽게 구별하는 방법은 레벨(Lev)이다.
레벨은 트리구조로 꽂혀지는 USB 호스트, USB 허브, USB 장비들의 단계를 나타내는데,
USB가 정한 최대 레벨은 5 단계이므로 04까지 가능하다.

저 키보드의 디바이스 번호를 보면 7이고, 상위 디바이스(Prnt)는 01, 즉 HCI 컨트롤러임을 알 수 있다. 그리고 그 키보드에는 MxCh=0 인것을 보아 아무것도 더 꽂을 수 없는 말단 장비임을 알 수 있다. 디바이스 번호는 꽂을 때 임의로 할당하는 식별 번호이므로, 꽂았다 뺐다를 반복하면 같은 장치라도 계속 바뀌게 된다. 7 이라는 숫자를 크게 의식하지 말자.

호스트 컨트롤러의 두번째 줄인 “B:” 는 Bandwidth를 나타내는데, USB1.1까지는 최대 90.0%(900), USB2.0은 최대 80.0%(800) 를 사용한다고 보고 현재 사용중인 대역폭을 나타낸다. Bus 02 번의 대역폭은 다른 Bus 와 달리 어느정도 사용중이며 이것은 키보드 때문에 그렇게 나타난다. #Int, #Iso 는 전송 방식에 따른 사용량을 나타내는 것이며, 인터럽트(interrupt) 방식인지 캠 같은 손실 가능한 데이터(isochronous mode)의 전송량을 알 수 있다.


지극히 개인적인 취미로 다음과 같이 구성해 보자.

위의 장비에 Dell 모니터에 있는 USB Hub를 꽂고 그 USB Hub에 내 SKY IM-7400 핸드폰을 꽂아 보자. 핸드폰을 컴퓨터와 연결하는 장비가 있어야 가능하다. (대개 살 때 주지 않나?)

T: Bus=04 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.2
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.1
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc=118/900 us (13%), #Int= 1, #Iso= 0
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 uhci_hcd
S: Product=UHCI Host Controller
S: SerialNumber=0000:00:1d.0
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms

T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 7 Spd=1.5 MxCh= 0
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=055d ProdID=0001 Rev= 1.00
S: Manufacturer=SAMSUNG
S: Product=USB SEM-DT35
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms

T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 6
B: Alloc= 0/800 us ( 0%), #Int= 1, #Iso= 0
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 2.06
S: Manufacturer=Linux 2.6.10-1.771_FC2 ehci_hcd
S: Product=EHCI Host Controller
S: SerialNumber=0000:00:1d.7
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=256ms

T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 13 Spd=480 MxCh= 4
D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=02 MxPS=64 #Cfgs= 1
P: Vendor=04b4 ProdID=6560 Rev= 0.0b
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=01 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms
I: If#= 0 Alt= 1 #EPs= 1 Cls=09(hub ) Sub=00 Prot=02 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=256ms

T: Bus=01 Lev=02 Prnt=13 Port=00 Cnt=01 Dev#= 14 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=02(comm.) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=10a9 ProdID=3197 Rev= 0.00
S: Manufacturer=SK Teletech Co.
S: SerialNumber=Serial Number
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=cdc_acm
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=32ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_acm
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none)
E: Ad=84(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms

Level 2 짜리가 생겼다. 두 번째 단계에 달려 있는 USB 장치라는 뜻이된다. 그 SK Teletech Co. 출신 장비는 14번을 할당 받았으며, 13 번 장치에붙어 있다. 장비 번호 13번은 또다른 허브임을 알 수 있다. 그런데, 그 허브는 “S:” 항이 없는 약간은 괴상한 놈이다. 나야 Dell 모니터에 붙어 있는 것을 알 수는 있지만, 저건 전혀 나오지 않는다. 대충만들었나? 그 허브는 MxCh는 4인 것을 보면 4 개를 꽂을 수 있는 것인데, 실제로 포트가 왼쪽에 두개 나와 있고 아래로 두개가 나와 있다.

이 허브는 하나의 interface에 altanate을 두어 0, 1로 구별하고 있다.


정리하자면,

  1. USB 장치들은 Tree 구조로 접속이 되어 있고(Lev, Prnt, Dev#),
  2. 각 장치들은 버전에 따른 속도가 달라지며 (Ver, Spd, Alloc)
  3. hub 장치들은 붙을 수 있는 장치 수가 0 보다 크며(MxCh)

이상으로 /proc/bus/usb/devices 에 기술되어 있는 USB 장치들의 기괴한 목록을 대충 살펴보았다. 다음에 기회가 되면 지금까지 설명하면서 빠진 것을 통해 얻을 수 있는 지식을 정리해보고자 한다