这篇文章来源于DevicePlus.com英语网站的翻译稿。
点击此处阅读本文第一部分 >
在本文中,我们将继续进行Arduino蓝牙手套的开发。我们将建立一个机械系统来获取手指的弯曲信息。同时,我们将会来了解如何整合IMU数据,无线封装和发送数据,使用Kinect以及如何在实际生活中使用Arduino蓝牙手套。我们强烈建议您先阅读Arduino蓝牙手套第一部分—基础来了解有关本项目的基础知识。
硬件
Arduino UNO R3 x 2
IMU 传感器 x 2
电线
电位计 0-10kOhm x 10
电阻 10 kOhm x 10
Xbee USB 适配器
Bluetooth Bee V2 x 2
9V 电池 x 2
9V 电池连接器 x 2
Kinect
手套 x 2
扣件 x 20
软件
Arduino IDE
Autodesk Inventor
LabVIEW
LabVIEW Robotics Module
Microsoft Kinect的 Kinesthesia工具包
Kinect SDK 1.5
Github
工具
PLA 塑料
螺母 M3 x 40
自锁螺母 M3 x 40
烙铁
锡
焊料
胶水
手指弯曲测量
首先,为了测量手指的弯曲(手指弯折)信息,我们必须将手指弯曲程度转换为电位计的旋转度。我们可以通过简单的机械系统来实现这一目的,如下图所示:
图1:用于测量手指弯曲程度的机械系统示意图
为了在现实生活中进行应用,我们需要先在实体建模编辑器(如Autodesk Inventor)中进行建模。
图2:用于测量手指弯曲程度的机械系统模型
接下来,我们需要将模型用3D打印技术制造出来。STL文件是所有3D打印机中常见的3D模型类型。只需要将所有模型分别导出成STL文件,并发送到3D打印机即可。
图3:手指机械系统的3D打印部件
取用电位计(不带黑色旋钮/手柄)、螺丝、螺母以及3D打印部件,然后如图4所示进行组装。
图4:手指基本单元组装
如图5所示拧入关节。然后,我们将黑色手柄与拧入的手指关节粘合在一起。
图5:手指关节组装细节
图6:带有扣件的基本手指单元
将关节拧紧后,我们要将组装好的手指粘合到手套上。粘合使用的是超强力的多用途胶水。粘合前,表面必须保持清洁和干燥。然后在两个表面涂一层薄薄的胶水,等待10到15分钟后,将表面用力按压几秒钟。如有必要,您可以在每个单元周围也散布一些胶水。建议您将其晾干约24小时。
* 黏贴时请切勿将手指伸入手套,使用纸板或其他材料。
图7:将基本单元粘合到近端指骨上(在每根手指的底部)
现在我们开始粘合手指关节。去除关节部分和两一个粘性扣件,然后将他们黏贴在手指的指甲上方(图8&9)。
图8:粘合手指关节
图9:手指关节组装(粘合完成)
将黑色手柄插入电位计孔中,以连接两个组装好的部件。
耐心对每根手指再重复9次相同的操作。
整个模块的接线图如下所示。
图10:Arduino手套电路图
现在,我们来对手指进行连线吧!
准备红色和黑色的电线,以及三根分别带有白色、黄色和黑色标记的电线。此处强烈建议将颜色编码,以避免混淆。
如图11所示,将黑色标记和黄色标记的电线焊接到电位计上。
图11:焊接电位计
用塑料扎线带捆扎电线,以避免其受任何机械外力破坏。
图12:用扎线带束紧电线
接下来,您需要将黑色标记的电线与黑色电线以及黄色和白色标记的电线焊接到电阻上。红色电线必须焊接到电阻的另一端,白色标记的电线连接至Arduino模拟输入端。
图13:焊接一个手指单元
图14:将黑色和红色标记的电线整合
焊接完所有单元后,我们将用热缩管对电线进行收缩,并用束线带将电线整合。
图15:手指与主体连接
图16:将组装好的手指与Arduino连接
图17:处理器主体(Arduino)
图18:IMU传感器连接
图19:组装好的Arduino手套
组装完成!我们继续进行编程部分。
安装新版本的 IMU Library。请参考 第一部分了解如何安装该库。
打开bending.ino 并将其上传到Arduino Uno。
#include "glove.h" TFinger Finger1 = TFinger(A0); TFinger Finger2 = TFinger(A1); TFinger Finger3 = TFinger(A2); TFinger Finger4 = TFinger(A3); TFinger Finger5 = TFinger(A4); void setup() { Serial.begin (9600); // Open the serial port Serial.println ("Be ready to set min, in 3..."); delay(1000); Serial.println ("2..."); delay(1000); Serial.println ("1..."); delay(1000); Finger1.setmin(); Finger2.setmin(); Finger3.setmin(); Finger4.setmin(); Finger5.setmin(); Serial.println ("Minimum is set"); Serial.println ("Be ready to set max, in 3..."); delay(1000); Serial.println ("2..."); delay(1000); Serial.println ("1..."); delay(1000); Finger1.setmax(); Finger2.setmax(); Finger3.setmax(); Finger4.setmax(); Finger5.setmax(); Serial.println ("Maximum is set"); Finger1.calibrate(); Finger2.calibrate(); Finger3.calibrate(); Finger4.calibrate(); Finger5.calibrate(); Serial.println ("Calibrated"); } void loop() { Serial.print ( Finger1.read() ); Serial.print ("\t"); Serial.print (Finger2.read()); Serial.print ("\t"); Serial.print (Finger3.read()); Serial.print ("\t"); Serial.print (Finger4.read()); Serial.print ("\t"); Serial.print (Finger5.read()); Serial.println ("\t"); delay(300); // }
您将会看到如图20所示的运行结果:
图20:手指弯折读取结果
请注意,必须遵循校准程序才能够对数据进行准确测量。
IMU数据融合在 Arduino蓝牙手套第一部分 – 基础 中,我们介绍了IMU传感器的基础知识。现在,我们将来学习如何整合陀螺仪和加速度计的数据。
首先,我们返回并查看之前的测量结果。
图21:IMU传感器读数
例如,陀螺仪返回12492数字值:
如果将陀螺仪配置为“测量范围 ±250 dps”,则该值将乘以0.00875 dps/数位,计算得到109.30 dps角速度。(109.30 dps表示具有该角速度的物体绕测量轴旋转一周大约需要四秒钟)。
如果将陀螺仪配置为“测量范围 ±2000 dps”,则该值将乘以0.07 dps/数位,计算得到874.44 dps的角速度。(874.44 dps表示具有该角速度的物体绕测量轴旋转一周大约需要2.5秒钟)。
传感器的灵敏度表示的是该传感器可检测到的最小变化值。请注意,范围约大,您从陀螺仪获得的灵敏度越低。
角速度是通过陀螺仪测量的值。因此,陀螺仪能够估计人体绕某个轴旋转的速度。在实际应用中,需要确定我们手套的位置。我们可以通过整合所有角速度值,然后除以时间变化,来估算当前角位置。
因为角速度的测量不是连续的,而是离散的,所以我们会得到一个叫做漂移的误差。之所以称为“漂移”,是因为即使身体处于静止状态,这些角位置变化的总和也会发生浮动。
我们一起看下面的陀螺仪漂移示例:
#include // Library for I²C #include // Library for working with IMU modules Gyroscope gyro; // Create an object to work with Gyroscope // Time Variables unsigned long starttime; unsigned long endtime; float dt; int ticker = 0; bool firstcall=true; // Indicator of a first iteration // Angle Variables float gyro_rateX, gyro_rateY, gyro_rateZ; float Pitch=0; float Roll=0; float Yaw=0; void setup () { Serial.begin (9600); // Open the serial port Serial.println ("Begin init ..."); // Display a message on the beginning of the initialization gyro.begin (); // Initialize the gyroscope at 100Hz Output Data Rate gyro.setRange(RANGE_2000); // set the gyroscope at 2000 dps range sensitivity Serial.println ("Init completed"); // Display a message about the successful initialization Serial.println ("Gyroscope"); } void loop () { endtime = micros(); // End time for the current Measurement if (firstcall) { firstcall=false; } else { dt = (float)(endtime - starttime)/1000000; // Get time beetween measurements gyro_rateX=gyro.readX_DegPerSec(); // Current Angle rate around the X-axis gyro_rateY=gyro.readY_DegPerSec(); // Current Angle rate around the Y-axis gyro_rateZ=gyro.readZ_DegPerSec(); // Current Angle rate around the Z-axis Pitch += 1 * gyro_rateX * dt; // Current Angle around the X-axis Roll += 1 * gyro_rateY * dt; // Current Angle around the Y-axis Yaw += 1 * gyro_rateZ * dt; // Current Angle around the Z-axis delay (10); } starttime = micros(); // Start time for the next Measurement if (ticker > 30) // Print Message every 300 ms { ticker=0; Serial.print (Roll); // Output angular velocity around the axis X Serial.print ("\t"); Serial.print (Pitch); // Output of the angular velocity around the Y axis Serial.print ("\t"); Serial.print (Yaw); // Output of the angular velocity about the Z axis Serial.print ("\t"); Serial.println (""); } else {ticker++;} }
如果让IMU传感器保持不动,您将会看到漂移现象(图22)。
图22:陀螺仪漂移演示
如上所述,由于有漂移的趋势,总和将会随着时间的增加产生误差。但我们可以通过计算和利用零速率电平来缓解漂移带来的影响。
有关零速率电平的定义在陀螺仪数据表的“2.6.2 零速率电平”一节中有详细描述。有这一现象的主要原因是在IMU上施加的机械应力,例如,在印刷电路板上焊接之后残留的应力。当有了机械应力之后,零速率电平会随温度略有改变,所以这一变化也许就可以被忽略了。
图23:基于零速率电平的陀螺仪测量
您可以点击此处查看在新版本IMU库中的执行细节。
经过这些强化后,我们就可以使用陀螺仪数据了,但是只能短期使用。
我们仍需要在长时间内能够保持稳定的信息。加速度计是一种测量加速度的设备。通过使用加速度计,我们可以根据计算获得的重力矢量来确定传感器工作平面的角度。但是,使用智能手套时,传感器将测量所有其他加速度,包括手臂的运动,这可能会破坏所测量的重力矢量。
低通滤波器可用于从随机加速度中过滤掉重力矢量。加速度计的测量值只适用于长期使用。
将传感器数据融合的最常见方法之一是使用功能强大的Kalman滤波器(很难理解,也很难在Arduino上实现)。
我们使用互补滤波器作为整合IMU数据的解决方案,这种滤波器非常易于理解,且容易在Arduino上实现。互补滤波器基本原理如下:
其中,Roll_i – 上一次迭代中计算出的横滚角
gyroRoll_i+1 –基于最近一次陀螺仪数据进行的最近一次测量所得到的角度变化
accelRoll_i+1 –基于最近一次的加速度计数据计算出的横滚角
Roll_i+1 –最新计算得到的带有互补滤波器的横滚角
该滤波器可以在短期内利用陀螺仪的动态特性,并通过加速度计数据在长期内消除误差。您可以自己进行测试,只需在Arduino IDE中打开imu_2.ino并将其上传到您的Arduino IDE即可。
更新信息发送端当我们获取测量数据时,必须使用无线蓝牙连接来将数据传送到PC。
首先,检查Bluetooth Bee是否已正确配置。将Bluetooth Bee安装在Xbee USB适配器上,将Bluetooth Bee换为AT模式,然后使用“AT+UART?”指令检查UART配置。Bluetooth Bee应返回“115200,0,0”(波特率115200位/秒,一个停止位,无奇偶校验位)。如果不是,请发送“AT+ UART=115200,0,0”指令来配置Bluetooth Bee,然后再次检查UART配置。检查后不要忘记关闭AT模式!
另外需要注意的是位于无线SD扩展板上的“串行选择”开关,该开关将指定将无线连接所读取的数据发送到何处。
图24:位于无线扩展板上的串行选择开关/ ©Arduino LLC
将其切换到MICRO位置。当处于MICRO位置时,蓝牙模块会连接到Arduino。请注意,Arduino仍连接到USB串口转换器。如果您从Arduino将数据写入串行端口,数据将会以两种方式发送:USB传送和无线传送。
将messaging.ino上传到Arduino。请注意,每次打开或重置Arduino时,它都会通过三个步骤进行校准:
陀螺仪零速率电平计算;
测量手指位置最小值;
测量手指位置最大值。
在计算陀螺仪零速率电平之前,请保持IMU静止不动。在测量手指位置最小值之前,请戴上Arduino手套并握紧拳头。在测量手指最大位置之前,请戴上Arduino手套并松开拳头。
在Arduino IDE中打开messaging.ino并将其上传到您的Arduino UNO中。
关闭Arduino电源,然后将Bluetooth Bee放置在无线扩展板上。请确保Bluetooth Bee不在AT模式下,并且将无线扩展板串行选择开关切换到MICRO位置。
用9V电池为Arduino Uno供电,并使用“1234”作为密码与您的Bluetooth Bee配对。确认配对成功后,您可以在设备管理器中找到您的无线蓝牙连接作为虚拟COM端口。
图25:与Bluetooth Bee配对
图26:设备管理器中的虚拟COM端口
从项目浏览器窗口中打开 Messaging.lvproj LabVIEW项目和 Messaging Test.vi。选择相关COM端口并运行。
图27:LabVIEW PC应用程序中显示的来自Arduino手套的信息
您将会看到Arduino Uno在串行端口中写入的数据已通过蓝牙传输,并从虚拟COM端口中读取。
添加Kinect测量表面上看,Kinect 是一款Xbox 360游戏设备控制器,可替代常见的游戏杆。实际上,它是一个功能强大的运动捕捉控制器,可获取您的姿态信息,并使您可以用手或者身体来控制游戏过程。虽然这个设备是为了游戏而开发的,但也可以在实际生活中使用。
想要在LabVIEW环境中使用用于Xbox 360的Kinect,您需要安装以下软件:
Microsoft Kinect SDK 1.5 (适用于Windows SDK v1.5的Kinect)
Microsoft .NET 4.0 Framework (Microsoft .NET Framework 4 (独立安装程序))
适用于Microsoft Kinect的Kinesthesia LabVIEW工具包
从项目浏览器窗口中打开 Kinect.lvproj LabVIEW Project和 Kinect Test.vi ,然后运行。如果正确安装了所有要求的软件,您将看到类似以下内容的视频和Kinect处理结果:
图28:视频与Kinect处理结果/ ©Kinesthesia
整合所有内容
现在,我们需要把所有内容整合到一个应用程序中。
打开 Arduino Gloves.lvproj LabVIEW Project。然后从项目浏览器窗口打开 Host Main.vi 。为左右手套蓝牙连接选择相应的COM端口。插入Kinect,并确保可以使用。
然后戴上Arduino蓝牙手套并打开电源,为校准提供所需要的必要条件。
之后,运行 Host Main.vi ,您将会看到以下内容:
图29:在一个应用程序中完成所有测量
请确认对每个手指的弯曲度进行了准确的测量,并且横滚角、俯仰角和偏航角与您的手的实际姿势相对应。
机器人控制Arduino蓝牙手套在现实生活中的机器人控制应用领域很有用。所有处理过的数据都可以通过UDP信息传输到任何第三方应用程序中。
图30:传送信息到第三方应用程序示意图
我们选择工业机器人手臂的模拟器—UDPPuma560 作为第三方应用程序的示例,同时添加了UDP接收器环路。 从项目浏览器窗口打开 Puma560 Simulator.lvproj, Host Main.vi 以及 Puma560 Simulator.vi 。
为左右手套蓝牙连接选择相应的COM端口。插入Kinect并确保可以使用。
然后戴上Arduino蓝牙手套并打开电源,并为校准提供所需的必要条件。
运行完这两个VI后,您将会得到以下结果:
图31:将处理后的数据导出到Puma560模拟器
请注意,您必须对从智能手套获取的数据进行正确的解译,而不应该直接使用没有经过任何处理的数据。例如,操作员的右手坐标不可能与机器人的手臂夹持器相同,所以您需要将测量数据从操作员的坐标系转换为机器人的坐标系。
演示: