原文连接:http://www.csksoft.net/blog/post/lowcost_3d_laser_ranger_2.html
2. 机械和结构部分对摄像头的改装由于我们使用了红外激光器,因此需要对摄像头做一些修改。
首先是要移除摄像头镜片中的红外截止滤光片。该滤光片的作用与前文提到的红外滤光片功能恰好相反:它将红外 光谱过滤。一般摄像头内都会含有这种滤光片。如果不移除,则只能够感受到很微弱的红外信号。(题外话,可以用拆 除截至滤光片的摄像头观察kinect投射出来的红外图案)
图:位于摄像头镜头中的红外截止滤光片 其次就是将前面提到的红外低通/带通滤光片安装到摄像头中,这里采用比较山寨的组装方式:用胶布固 定在镜头前面,不过效果也可以接受。 图:将红外低通滤光片安装在摄像头上 制作激光器、摄像头的固定平台这里使用了轻质的木板来安装摄像头和激光器。选择它的主要原因是容易加工。如果有条件,可以考虑使用热缩涨 比率小的金属或者塑料材料来固定。
图:使用木板作为固定摄像头、激光器的材料 在木板上打孔,保证激光器和摄像头能正好装入,2个孔之间的距离是前文提到的160mm左右。不过不必 很精确,因为它的精确数值可以通过校正得到。这样安装的时候就比较省心。在给激光器打孔的时候要注意角度的问题 。 图:木板打孔后,将摄像头和激光器装入
图:在木板底部打孔,安装螺丝柱,用于固定在舵机转盘上 底座和舵机安装我是用了用于安装仪器的塑料盒子作为扫描仪的底座,这类盒子可以在taobao上找到。
图:选用的塑料盒子和舵机 将盒子顶板开孔,使得舵机能够放进去:
图:将盒子开孔 图:将舵机嵌入盒子顶板 最后将之前的摄像头固定支架安装于舵机上:
3. 电子系统制作这里的电子系统主要功能是从PC接受指令并控制舵机转到指定角度的。由于摄像头已经是USB接口了,所以这里的电 子系统不用去处理摄像头的信号。
目前PC外设使用USB几乎已经成为了一种标准,为了使得设备使用尽可能方便,如果能做到免驱动,那就更加完美了 。
这里我才用了我们RoboPeak机器人团队设计的一款AVR开源控制版:RoboPeak Usb Connector[2]来实现这部分功能。它使用单片AVR(Atmega88)芯片通过软 件方式模拟出USB协议栈,并且使用了HID协议使得无需在PC上安装驱动程序。对于这部分的细节属于固件实现部分,将 在后文提到。
图: 我们RoboPeak团队的开源USB方案:RP USB Connector(蓝色PCB) 这里列出本制作中电子系统所实现的功能
实现了一个HID类的USB设备,无需第三方驱动程序支持
支持通过USB接受指令,控制舵机运转到指定角度
可通过USB指令,开启/关闭激光器
通过一个双米字LED显示屏,显示当前舵机的角度
支持用户通过设备上按钮手工设置舵机角度
对于USB设备的实现、接收处理USB指令等属于固件范畴的职责,这里将不做讨论。这里使用了RP USB Connector, 因此其固件已经支持了此部分的基础操作,也可以在他的介绍页面[2]查看详情。
米字LED数码管的驱动由于2个米字形LED含有16多个独立的LED需要独立控制,RP USB Connector上并没有如此多空闲IO口。因此这里的做 法是很传统的采用74595串行转并行输出芯片。RP USB Connector上通过SPI总线进行控制。
图:使用2个74595芯片驱动双米字LED数码管 扩充RP Usb Connector由于RP Usb Connector主要功能是做为AVR芯片编程器和通用USB开发版的,上面并没有舵机控制和激光 器控制功能(需要三极管扩流)。因此需要做一块额外的电路扩充它的功能。电路比较简单,这里就不介绍了,可以参 考本章节模块给出的电路图。 图:在RP USB Connector基础上做扩充电路 制作角度手工控制面板这部分做的比较粗糙,主要就是在塑料盒子外边加装按钮,就不多介绍了,给一些制作的照片。 图:按钮(正面) 图:按钮(背面) 总装最后将所有线路连接起来,并关闭盒子,设备的安装就大功告成。 这里给出一个早期的视频:
电子系统电路原理图:RoboPeak USB Connector电路图: 这部分请访问位于google code托管的开源项目:http://code.google.com/p/rp-usb-connector/
扩展电路/LED驱动电路原理图: 目前本制作的所有源代码和电路也已经托管于Googe code, 请访问如下地址下载:
http://code.google.com/p/rp-3d- scanner
4. 固件以及PC通讯这里的固件自然就是运行在RoboPeak USB Connector AVR芯片上的固件代码了。这里只大致列出实现的思路和原理 。具体的细节以及基础知识不做介绍。源代码可以在本制作的google code项目页面[3]上找到。
固件实现的功能
如前文所述,固件实现了:
- 通过软件方式模拟出USB1.1协议栈(使用了v-usb库[4])
- 实现了HID(Human Input Device)类的USB设备进行通讯,在PC上无需外驱动
- 控制舵机角度
- 驱动LED数码管显示
同时,固件代码采用了我之前写的Arduino-Lite[5]轻量级AVR固件库。因此如果需要使用这里的固件代码,请在 google code上下载并配置Arduino-Lite[6]。
接下来我将跳出一些典型问题介绍
HID-USB设备的模拟及与PC通讯
RoboPeak USB Connector使用的是不含有USB接口的AVR芯片。因此,USB通讯支持是采用软件方式进行的。索性目前 v-usb开源库[4]已经提供了很优秀的封装。
软件模拟usb的优势在于可以降低设备成本(带有USB的AVR芯片成本较高),缺点是稳定性和速率上不如硬件实现。 对于本制作,稳定性和速度并不关键。
在使用USB与PC通讯时有一个烦恼的问题是驱动。直接为系统编写驱动程序会提升本制作的难度,同时对于64位 Windows系统,微软要求驱动程序进行签名。目前也有一种可以在用户态实现usb驱动的方案:libusb。但是,同样在64 位Windows系统上,这个做法就不管用了。
这里采用了另一种思路:利用那些OS自带驱动支持的USB类设备。(USB协议中预先定义了几类USB设备的种类,比如 Mass Storage就是平时用的移动硬盘、UVC设备常用于实现摄像头、HID设备用于实现键盘鼠标。OS往往会自带驱动支持 这类设备)。这里我也使用了HID类设备。理由如下:
- 协议比较简单,通讯单位也是数据包
- 支持USB1.1低速率规范,可以用v-usb实现
- 在Windows、Linux、Mac上均可以通过OS提供的用户态API与HID设备通讯
采用了HID设备后,及时在计算机上第一次使用本扫描仪,OS也能直接识别,不会要求安装驱动或者配置文件。
图:本扫描仪在PC上识别为HID设备
接下来的问题是如何利用HID设备进行通讯了。这里的做法千差万别。为了提高通讯质量,这里我使用 了带有checksum交验的,基于数据包的通讯协议,将它运行在HID协议之上。因为本固件是基于RP USB Connector固件 的缘故,我直接采用了用于AVR芯片烧录器的STK500v2协议。 图:本制作的通讯构架 舵机驱动逻辑 在AVR上有很多舵机驱动库,这里我使用的是RoboPeak对Arduino自带舵机库的修改版本,该版本使用 Arduino-Lite进行了重写,精度上也较高。但这部分不影响具体效果,因此就不多介绍了。 数码管驱动逻辑 在RP USB Connector上引出了SPI总线,因此很自然的我使用SPI协议驱动74595芯片,直接通过AVR控制 数码管的每个LED,从而支持显示任意的图案。 要注意的是,由于双米字管的每个字符上相同位置的LED公用信号线,因此在驱动上需要采用传统的扫 描方式,轮流点亮LED。 5. 图像处理和渲染图像处理部分就是第一篇**[1]所介绍的几个步骤:
- 获取摄像头原始画面
- 通过摄像头校正参数,消除画面扭曲
- 提取和识别激光光斑的位置
- 通过激光光斑的位置,代入距离求解公式,算出对应点真实距离
本制作使用了OpenCV库简化图像计算的开发难度。同时这样也有利于代码的跨平台移植。对于摄像头的校正,会在 后文介绍。
这部分的细节已经在第一篇**中详细介绍了,因此这里给出程序运作中的截图作为示意:
图:对摄像头画面进行扭曲校正并识别激光点的过程
由于采用了红外激光器,在加装滤光片后,背景光干扰被有效的去处。画面上除了激光光斑外,几乎看不到别的内 容。红外激光在摄像头中以偏紫色的色彩显示。
上图中显示了画面中心点的激光中心坐标值。这样做的目的是用于后期进行测距参数的校正。而使用中心点的原因 在第一篇**中已经介绍。
渲染点云
在视频中看到了实时扫描并显示点云的画面。在明白了扫描原理后,这点就没什么特别的了。基本上都是基本的3D 渲染得技巧。我使用了Irrlicht[7]开源3D引擎简化了这部分的实现工作。
除了自行编写软件外,也有很多工具可以用来查看3D点云。比如开源的MeshLab[8],Blender[9]以及Matlab。在后 文我将给出可以在Meshlab中观看的点云数据。
要产生可被这类软件读取的文件很容易,像MeshLab支持如下格式的文本点云数据
x1,y1,z1
x2,y2,z2
...
xn,yn,zn
6. 校正当完成所有部分制作和PC端软件后,就可以进行校正工作了。校正主要分为:相机校正和测距校正。
相机校正
我使用自己打印的Chessboard图案,分别在不同距离和位置下拍摄了不同画面。校正工具使用了matlab的Camera Calibration Toolbox。它的信息请参考第一篇**的参考文献[10]。OpenCV也包含了相机校正功能,也可以直接使用 。
图:用棋盘图在不同位置下拍摄画面 图:使用matlab进行校正时识别出的Inner Corner 图:校正计算的外部参数(对本制作无用) 在完成校正后,将得到如下的校正参数: Calibration results (with uncertainties):
Focal Length: fc = [ 935.44200 929.73860 ] ? [ 11.29945 10.64268 ]
Principal point: cc = [ 149.00014 233.25474 ] ? [ 17.13538 11.11605 ]
Skew: alpha_c = [ 0.00000 ] ? [ 0.00000 ] => angle of pixel axes = 90.00000 ? 0.00000 degrees
Distortion: kc = [ - 0.13196 -0.05787 -0.00358 -0.01149 0.00000 ] ? [ 0.04542 0.12717 0.00195 0.00565 0.00000 ]
Pixel error: err = [ 0.24198 0.25338 ]
Note: The numerical errors are approximately three times the standard deviations (for reference).
对于这里的应用,之需要关心Focal Length、Principal point、Distortion的几组参数。可以使用OpenCV的 cvInitUndistortMap/cvRemap读取校正参数并完成画面扭曲消除。
测距参数校正
|