这里会显示出您选择的修订版和当前版本之间的差别。
后一修订版 | 前一修订版 | ||
ideas:kinect_arduino [2015/12/24 15:18] gdw 创建 |
ideas:kinect_arduino [2015/12/24 22:34] (当前版本) gdw |
||
---|---|---|---|
行 8: | 行 8: | ||
结束 | 结束 | ||
+ | |||
{{:ideas:k6.jpg?200|}} | {{:ideas:k6.jpg?200|}} | ||
+ | |||
电源,arduino uno,机械臂 | 电源,arduino uno,机械臂 | ||
+ | |||
+ | |||
{{:ideas:k7.jpg?200|}} | {{:ideas:k7.jpg?200|}} | ||
+ | |||
+ | |||
+ | kinect for windows | ||
+ | |||
+ | {{:ideas:k8.jpg|}} | ||
+ | |||
+ | kinect演示界面 | ||
+ | |||
+ | 一些简单的说明。 | ||
+ | 关于Arduino: | ||
+ | 在这就不多做介绍了,各位肯定比我了解的要多,我买了这个板子前后加一起还不到10天。 | ||
+ | |||
+ | |||
+ | 为什么要用Kinect: | ||
+ | 这真是一个很好玩的东西,功能很强大,如果有一定编程经验上手的话也不算很难。Kinect+Arduino是绝佳的交互组合。可以做出很多有意思的东西。 | ||
+ | |||
+ | |||
+ | 这个项目是怎么产生的: | ||
+ | 现在网上已经由很多Kinect+Arduino的经验分享了,比如遥控车,遥控直升机等等。控制机械臂的我暂时还没有发现。灵感来源于前段时间看的一个日本机器人技术的视频,当然视频里的高度光凭我一个人和这些设备是无法达到的。Kinect+Arduino这个组合最核心的一个词就是--(体感)交互,单纯用Arduino是无法完成这个任务的。于是我翻出了以前买的机械臂,做出了这个简易的交互式控制机械臂。 | ||
+ | |||
+ | 下面对各个部分而做出解释 | ||
+ | |||
+ | 首先是硬件。 | ||
+ | 1.Kinect for Windows一台 | ||
+ | 为了便于开发我没有选择Xbox版的Kinect,因为据说有些功能在Windows下是不支持的。 | ||
+ | 2.Arduino Uno一块 | ||
+ | 没啥可说的,大家都懂。 | ||
+ | 3.码垛机 | ||
+ | 网上买的,现成货,自己装起来就可以了。这个码垛机是4度的,也就是4个舵机,分别控制: | ||
+ | 腰部(底座左右旋转) | ||
+ | 大臂(大臂上下旋转) | ||
+ | 小臂(小臂上下旋转) | ||
+ | 腕部(腕部左右旋转) | ||
+ | 由于是码垛机,要保持腕部一直处于水平状态,所以它的自由度不像传统的机械臂那样高,小臂的活动范围受到大臂的角度限制。目前腕部的舵机还没有用上,可以忽略。 | ||
+ | |||
+ | 接下来是软件。 | ||
+ | 首先说明的是我暂无开源的打算,因为很多地方还需要优化和提高,但是一些概念性的问题我是可以回答的。软件一共分为2个部分,分别是Kinect端和Arduino端 | ||
+ | |||
+ | |||
+ | 1.Arduino端 | ||
+ | Arduino的主要目的是接收来自Kinect(通过串口通信实现,在后面说明)的数据,并向舵机发出信号旋转相应的角度。这个程序需要对接收到的数据进行分类判断,哪一条是控制大臂舵机的,哪一条是控制小臂舵机的。至于如何实现,Arduino的IDE提供了很多String的例子。我们要把接收到的每一条指令先进行预处理,在根据情况进行操作,下面是个简单的例子: | ||
+ | <code c> | ||
+ | Servo servoA; //舵机对象 | ||
+ | boolean readCompleted = false;//是否完成读取串口数据 | ||
+ | |||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | Serial.begin(9600); //开启串口通信,比特率需要根据自己的硬件调整 | ||
+ | servoA.attach(10); //由PWM10控制该舵机 | ||
+ | } | ||
+ | |||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | if(readCompleted)//判断串口是否接收到数据并完成读取 | ||
+ | { | ||
+ | servoA.write(serialString.toInt());//把角度发送给舵机控制其旋转 | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | //串口事件处理方法,参考:http://arduino.cc/en/Tutorial/SerialEvent | ||
+ | //功能是读取串口数据,并改变readCompleted的值以示读取完成 | ||
+ | void serialEvent() | ||
+ | { | ||
+ | while(Serial.available()) | ||
+ | { | ||
+ | char inChar = (char)Serial.read(); | ||
+ | if(inChar != '\n') | ||
+ | { | ||
+ | serialString += inChar; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | readCompleted = true; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | 这个例子演示了如何从串口接收数据并且控制舵机。当然还有很多因素需要考虑,比如舵机的旋转限制,数据与舵机编号的对应等等。对String进行预处理的方法可以参考IDE给出的例子,里面写的很详细,而且功能也完全够用。 | ||
+ | |||
+ | 在上面那层有一些错误,应该是这样的 | ||
+ | <code c> | ||
+ | if(readCompleted)//判断串口是否接收到数据并完成读取 | ||
+ | { | ||
+ | servoA.write(serialString.toInt());//把角度发送给舵机控制其旋转 | ||
+ | serialString = "";//清空串口数据变量 | ||
+ | readCompleted = false;//标示读取未完成,以进行下一次读取 | ||
+ | } | ||
+ | </code> | ||
+ | 2.Kinect端 | ||
+ | Kinect端的程序用Kinect SDK for Windows的例子上加以修改的,其主要功能是取得骨骼关键点(也就是关节)的数据,并进行一系列计算,计算出每一个舵机需要旋转的角度,并通过串口发送给Arduino。 | ||
+ | |||
+ | |||
+ | 开发环境是VS2010+Kinect SDK for Windows,为了演示方便用的是WPF程序。具体的代码这里就不写了,比较复杂,感兴趣的看看他们给的例子就可以了。 | ||
+ | |||
+ | |||
+ | 在例子中,提取骨骼数据已经写好了,所以我们要做的是处理这些关节数据并进行计算。下面是控制各个舵机所用到的骨骼数据: | ||
+ | |||
+ | |||
+ | 腰部: | ||
+ | 由我的左小臂控制,提取到左手肘和左手腕的数据,并计算出角度。 | ||
+ | 大臂: | ||
+ | 由我的右大臂控制,提取到右肩和右手肘的数据,并计算出角度。 | ||
+ | 小臂: | ||
+ | 由我的右小臂控制,提取到右手腕和右手肘的数据,并计算出角度。 | ||
+ | 腕部: | ||
+ | 暂不使用 | ||
+ | |||
+ | |||
+ | 至于如何计算角度,因为我先把三维空间的点映射到二位空间内,所以可以用横纵坐标加上反三角函数计算出角度。当然,还是有很多其他因素需要考虑,比如人手臂的活动范围是很大的,如何对应到机械臂的活动范围上等等。 | ||
+ | |||
+ | |||
+ | 计算好角度后,在通过串口发送给Arduino。在发送时可以根据不同舵机做出一些标示以便Arduino端的程序分类,比如 | ||
+ | servoA:50 | ||
+ | servoB:70 | ||
+ | servoC:80 | ||
+ | 这样Arduino端的程序可以用startsWith()和subString()来处理这些数据了 | ||
+ | |||
+ | Kinect端界面。骨骼和关节的追踪(忽略我诡异的姿势) | ||
+ | |||
+ | {{:ideas:k9.jpg?200 |}} | ||
+ | |||
+ | 一些补充: | ||
+ | 1.可以添加一些控制整个机械臂启停的判断。在我的程序里,两手靠近则机械臂启动,两手自然下垂则机械臂返回默认姿态(最后一张动图的收起姿态) | ||
+ | 2.Kinect SDK for Windows提供的功能是有限制的,而且并没有开源,有更高追求的玩家可以尝试用OpenNI。 | ||
+ | 3.下一步我准备加一个机械爪在腕部,通过手势识别可以控制抓握和松开。 | ||
+ | |||
+ | 原文链接:http://tieba.baidu.com/p/2902331289?see_lz=1 |