用户工具

站点工具


ideas:kinect_arduino

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
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
· 最后更改: 2015/12/24 15:18