Quantcast
Channel: Sam的技术Blog
Viewing all articles
Browse latest Browse all 158

OpenNI2 研究

$
0
0
作者:Sam (甄峰)  sam_code@hotmail.com

 
0. 背景介绍:
近期要研究ROS Xtion Driver. 在ROS系统下, Xtion Driver是openni2_camera, 它读取Xtion数据并将数据发布到各Topic供其它Node使用。但研究下来,其实openni2_camera仅仅是冰山露出海面的部分。它构建了类似Linux Driver 中的Device,Driver 概念,并使用Manager管理Device。看起来很清晰,但数据处理,Device具体处理等庞大的部分,其实并不在这个包内。二是另有玄机。现在就将这部分内容大概的理一下。
 
 
1. openni2_camera文件结构和组成研究:
这个Package是Asus Xtion and Primesense Devices的Driver。
下载并察看之。
 
分析组成结构:
文件组成和结构的分析,照例是看CMakefiles.txt
A:  首先生成一个动态库,名为:libopenni2_wrapper.so:
 
add_library(openni2_wrapper src/openni2_convert.cpp
   src/openni2_device.cpp
   src/openni2_device_info.cpp
   src/openni2_timer_filter.cpp
   src/openni2_frame_listener.cpp
   src/openni2_device_manager.cpp
   src/openni2_exception.cpp
   src/openni2_video_mode.cpp )
target_link_libraries(openni2_wrapper ${catkin_LIBRARIES} ${PC_OPENNI2_LIBRARIES} ${Boost_LIBRARIES} )
 
可以看到,它由src下的一些文件构成。同时,请注意,这个库依赖于${PC_OPENNI2_LIBRARIES}
它是谁呢?是/usr/lib/OpenNI2/Drivers中的各个库文件,这个库提供对设备的识别,操作,对数据的处理等大量的工作。
 
 
B:test_wrapper应用程序
add_executable(test_wrapper test/test_wrapper.cpp )
target_link_libraries(test_wrapper openni2_wrapper ${Boost_LIBRARIES})
这个程序用来尝试使用A库。由test/test_wrapper.cpp构成,并依赖于A 库。
 
 
C:生成主要的动态库:libopenni2_driver_lib.so:
add_library(openni2_driver_lib src/openni2_driver.cpp ) target_link_libraries(openni2_driver_lib openni2_wrapper ${catkin_LIBRARIES} ${Boost_LIBRARIES} ) add_dependencies(openni2_driver_lib ${PROJECT_NAME}_gencfg ${PROJECT_NAME}_generate_messages_cpp)
它原来于A库。
 
D:nodelet 库:
add_library(openni2_camera_nodelet ros/openni2_camera_nodelet.cpp )
target_link_libraries(openni2_camera_nodelet openni2_driver_lib ${catkin_LIBRARIES} ${Boost_LIBRARIES} )
add_dependencies(openni2_camera_nodelet ${PROJECT_NAME}_gencfg)
这个是为nodelet创建的库。 它依赖于C库,则间接依赖于A库。
 
 
E:node:
add_executable(openni2_camera_node ros/openni2_camera_node.cpp )
target_link_libraries(openni2_camera_node openni2_driver_lib ${catkin_LIBRARIES} ${Boost_LIBRARIES} )
add_dependencies(openni2_camera_node ${PROJECT_NAME}_gencfg ${PROJECT_NAME}_generate_messages_cpp)
与nodelet地位相同,但它是创建一个Node。利用Node发布Topic。
它依赖于C库,则间接依赖于A库。
 
 
F:list_devices, usb_reset应用程序:
比较简单的Linux程序,打开设备并设置。
 
 
2. libopenni2_wrapper.so 中各种概念(Manager, Device, Driver)的分析
 2.1: Manager:
class OpenNI2DeviceManager:它主要用来管理Device。对插入和拔出设备进行监听。随时维护正在插入设备的列表。并得到他们的信息。
 
在构造函数中,
A: 首先调用底层库的: openni::OpenNI::initialize()
B: device_listener_ = boost::make_shared(); 创建了OpenNI2DeviceListener class 的对象。并给出对象指针。
 
先着重谈谈OpenNI2DeviceListener 这个Class。
它是 public openni::OpenNI::DeviceConnectedListener,
                             public openni::OpenNI::DeviceDisconnectedListener,
                             public openni::OpenNI::DeviceStateChangedListener
的子class.
 
在OpenNI2DeviceListener 构造函数中,它把自己的对象加入监听队列:
openni::OpenNI::addDeviceConnectedListener(this);
    openni::OpenNI::addDeviceDisconnectedListener(this);
    openni::OpenNI::addDeviceStateChangedListener(this);
 
并获取已经连接的Device信息:
    openni::Array device_info_list;
    openni::OpenNI::enumerateDevices(&device_info_list);
 
    for (int i = 0; i < device_info_list.getSize(); ++i)
    {
      onDeviceConnected(&device_info_list[i]);
    }
 并把这些设备记录下来。
 
它主要用来监听设备的连接和断开。
 
device_manager.getDevice(uri);
则返回一个新创建的Device。
 
 
2.2:Driver;
在构造函数中。
1. 利用OpenNI2DeviceManager的static函数getSingelton()获取到Manager。
2. 在initDevice()中,利用Manager的getDevice()获取到当前Device。(此处会初始化Device)
3. advertiseROSTopics();
 
现在主要分析advertiseROSTopics()
 
 
 
 
 

 

Viewing all articles
Browse latest Browse all 158

Trending Articles