现在的位置: 首页 > 综合 > 正文

kinect 无法在我的android开发板上显示的分析

2013年08月11日 ⁄ 综合 ⁄ 共 10334字 ⁄ 字号 评论关闭

之前在网上发现黑客已经将kinect移植到android上,使用的beagleboard平台。公司想在kinect上深耕一下,所以需要将kinect在公司的android开发板上实现。记录以备忘。

 

一,按照黑客的教程,将之移植到beagleboard C4平台上。挺顺利。但深度图像只能维持几秒钟,因beagleboard不是我的最终目的,此问题搁置,beagleboard作为参考。黑客的教程如下:

http://www.noritsuna.com/archives/2011/01/openframeworks_kinect_android.html

顺便说一下,配置开发工具很麻烦,尤其是有些需要翻墙出去下,所以建议下载上面网页结尾处作者提供的完整软件包。解压后修改一下环境变量即可用。可以更懒一下:新建一个跟作者相同的用户名,将包解压到相应的文件夹,整个工程及其软件就可以用了。

 

二、将之移植到自己的android开发板。硬件平台就不具体说了,不是国际大厂的。

出错:加速度计显示正常,但深度图像没有显示,全黑。

到此为止,我一直没有仔细看代码。呵呵。没办法了,看代码吧。

 

框架:openframework

流程:openframework->ofxAndroid->ofxKinect->freenect->libusb之后就是linux内核?

前面不说了,可以借助打印log进行分析。没有显示的原因是ofxKinect::threadedFunction()函数中,

 

  


最后一条语句设置回调函数,具体实现如下
将回调函数赋值给dev->depth-cb, 之后调用freenect_start_depth(kinectDevice);
函数fnusb_start_iso()将参数depth_process设为回调函数,
 
//在此函数中将iso_callback函数设为回调函数
 
而iso_callback函数又会调用strm->cb,depth_process。
 
depth_process中会执行dev->depth-cb。
调来调去的真的很麻烦。

 

至此,整个流程结束。那回调函数会在何时调用?也就是libusb_fill_iso_transfer函数中的  transfer->callback会在哪里被调用执行?
在ofxKinect用cscope搜一下callback,只有usbi_handle_transfer_completion回调用到transfer->callback,那usbi_handle_transfer_completion会在哪里被调用?再搜

 

 

有八九条,我们只关注标志为 LIBUSB_TRANSFER_COMPLETED的,只有一条,handle_iso_completion函数。搜handle_iso_completion

 

reap_for_handle   ---  op_handle_events  ,此函数被设置在const struct usbi_os_backend linux_usbfs_backend 结构体中,赋值语句:
.handle_events = op_handle_events,
 
看看linux_usbfs_backend 是不是引用,还有.handle_events在哪里被调用?
在libs/libusb/core.c中
 

 

在libs/libusb/io.c中函数handle_events(){   usbi_backend->handle_events}
io.c中有两处调用到handle_events()函数
4 io.c          libusb_handle_events_timeout 1946 r = handle_events(ctx, &poll_timeout);
5 io.c          libusb_handle_events_locked  2022 return handle_events(ctx, &poll_timeout);
正确的调用应该是第二个,libusb_handle_events_locked,
搜libusb_handle_events_locked,除了函数定义只有一处头文件的声明。看起来上面分析不对,那是libusb_handle_events_timeout是正确调用?
libusb_handle_events_timeout被
 
调用,
搜libusb_handle_events,排除被bulk及control接口调用,只有在libusb10.c的两处
1 usb_libusb10.c fnusb_process_events      66 return libusb_handle_events(ctx->ctx);
2 usb_libusb10.c fnusb_stop_iso           245 libusb_handle_events(ctx->usb.ctx);
2是usb停止时的调用,1应为我们的目标,
 
看到fn了,呵呵,我们的路应该是正确的。
 
搜freenect_process_events,libs/libfreenect/libfreenect.hpp中
 
     // Do not call directly, thread runs here
呵呵,终于到头了。

 

 

 

整个流程就是这样,但对无法显示的问题还是无解。需要log。
先这样,将libusb的log打印出来再说。没有log就像瞎子一样。

 

 

 

 


4.15日编辑
今天把libusb的log输出出来了,写下以备忘。
libusb的log部分实在libusb.h中定义的
最终所有的log输出都定位到usb_ofLog(level, fmt)函数,在core.c中
libusb的日志输出是标准的输入输出。有个方案,可以在上面的函数中将日志保存到一个文件中。我用的是另一条路:
采用android的日志模式
1、修改libusb.h,修改成这样
 
主要是上面的enum,将第一个赋值为3,另外将几个宏定义重定位到另一个函数usb_ofLog,这个函数需要我们自己改。
在core.c 最后添加如下:
 
见android的日志规则引用进来。之后重编译,就可以看到可爱的日志啦。

 

 

4.26日更新

 

已经在自己的开发板上跑起来了。有图像输出,但只是二值图,这个应该是上层画图的时候的问题。先记录一下解决的过程。

libusb日志打印成功后,分析得知libusb得到的数据为全0,libusb的底层支持是usbfs,所以跟踪到kernel的usbfs部分,usb/core/devio.c中,有函数processcompl(),

将语句

if (as->userbuffer && urb->actual_length) {

修改成 
if(as->userbuffer){
之后图像能够正常输出,跟板子的提供商联系,urb->actual_length在usb core中没有被赋值。bug
他提供的解决方案,
在driver/xxx/usb/dwc_otg/dwc_otg_hcd_intr.c中
if (++_qtd->isoc_frame_index == urb->number_of_packets) {前加下面的语句
urb->actual_length += frame_desc->actual_length;
最后的结果是:
default:
DWC_ERROR("%s: Unhandled _halt_status (%d)/n", __func__,
 _halt_status);
BUG();
break;
}
urb->actual_length += frame_desc->actual_length;
if (++_qtd->isoc_frame_index == urb->number_of_packets) {

 

如果只是按照他提供的方案改,帧率很低,原因待分析。

【上篇】
【下篇】

抱歉!评论已关闭.