极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 38818|回复: 21

kinect+processing+arduino体感小车

[复制链接]
发表于 2014-8-24 00:19:08 | 显示全部楼层 |阅读模式
本帖最后由 小智 于 2014-9-2 21:40 编辑

      从上年的十月份开始接触arduino到现在快有一年的时间了,当第一次看见用程序控制的LED一闪一闪的兴奋的不得了,经过一年时间的不断的摸索与学习,觉得自己的进步还是很明显。极客工坊是我常逛的论坛,从这里学到了很多东西,先感谢各位!这是我第一次发帖,如有写的不好的地方希望各位见谅!
        我这次diy的作品是体感小车,这种小车用到的最重要的三个工具是arduino、kinect、processing。Arduino不说估计都比我明白。Kinect就是xbox360体感游戏机的一个传感器。另一个就是processing,说到prosessing它与arduino的关系那是非常的紧密,arduino的编译器貌似就是根据processing的编译器制作出来的,而且两个项目都是开源的,processing也和arduino一样包含大量的库,这次我们用到控制kinect传感器的库是SimpleOpenNI。
       先说说这个项目的基本原理吧。首先kinect传感器识别人体在空间的信息,接着将数据传到processing,processing可以识别人体的骨架即可以特定的识别人的手掌或胳膊的位置,当手掌摆动到设定的位置,processing就可以通过无线串口传输数据给arduino单片机。这样我们就可一站在kinect传感器面前,挥一挥手就可以轻松的控制我们的无线小车了。
由于这个diy电脑端要配置的内容较多,短时间内也出不了完整的教程,所以这次主要向各位展示下我的diy作品。(未改完,过一段时间将视屏、配置文件的压缩包链接附上)这是视屏网址:  

[pre lang="processing" line="1"]import java.util.Map;
import java.util.Iterator;
import SimpleOpenNI.*;//begin the library of kinect
import processing.serial.*;//begin the library of serial port
Serial myPort;  // Create object from Serial class
SimpleOpenNI context;
int handVecListSize = 20;
float value_x;//X坐标map值
float value_y;//Y坐标map值
int value_x_;//整型X坐标map值
int value_y_;//整型Y坐标map值
Map<Integer,ArrayList<PVector>>  handPathList = new HashMap<Integer,ArrayList<PVector>>();
color[]       userClr = new color[]{ color(226,51,237),//用户的界面,横线、竖线
                                     color(126,81,232),
                                     color(107,145,224),
                                     color(134,216,219),
                                     color(156,211,177),
                                     color(249,23,126)
                                   };
void setup()
{
  size(640*2,480);//显示界面的大小
  context = new SimpleOpenNI(this);
  if(context.isInit() == false)
  {
     println("Can't init SimpleOpenNI, maybe the camera is not connected!");
     exit();
     return;  
  }   
  context.enableDepth();// enable depthMap generation
  context.setMirror(true); // 启用镜像,这是干嘛的
  context.enableRGB();//使能RGB图像
  context.enableHand();//使能手势识别
  context.startGesture(SimpleOpenNI.GESTURE_WAVE);//摆手启动手势控制
String portName = Serial.list()[0];//建立串口
  myPort = new Serial(this, portName,9600);//设置波特率
}

void draw()
{
  context.update();//更新相机传来的数据
  background(0,255,0);//设置背景颜色
  image(context.depthImage(),0,0);//设置显示深度图在背景上的位置,
  image(context.rgbImage(), context.depthWidth()+5,0); //设置RGB图在背景上显示的位置
  if(handPathList.size() > 0)// draw the tracked hands  
  {   
    Iterator itr = handPathList.entrySet().iterator();     
    while(itr.hasNext())
    {
      Map.Entry mapEntry = (Map.Entry)itr.next();
      int handId =  (Integer)mapEntry.getKey();
      ArrayList<PVector> vecList = (ArrayList<PVector>)mapEntry.getValue();
      PVector p;
      PVector p2d = new PVector();   
        stroke(userClr[ (handId - 1) % userClr.length ]);
        noFill();
        strokeWeight(1);        
        Iterator itrVec = vecList.iterator();
        beginShape();
          while( itrVec.hasNext() )
          {
            p = (PVector) itrVec.next();            
            context.convertRealWorldToProjective(p,p2d);
           // vertex(p2d.x,p2d.y);//显示移动点后面的尾巴
          }
        endShape();     
        stroke(userClr[ (handId - 1) % userClr.length ]);
        strokeWeight(4);
        p = vecList.get(0);
        context.convertRealWorldToProjective(p,p2d);
        line_display();//当追踪到手时,显示按键坐标
        //stroke(255,0,0);
        //strokeWeight(2);
        //ellipse(p2d.x,p2d.y,10,10);//圆心
        //fill(110,90,10);
        //line(p2d.x-10,p2d.y,p2d.x+10,p2d.y);//圆心横
        //line(p2d.x,p2d.y-10,p2d.x,p2d.y+10);//圆心竖
        /************************************************************************/
        /***************************发送指令(以下部分)**************************/
        /************************************************************************/
        if((p2d.x>213)&&(p2d.x<426)&&(p2d.y>160)&&(p2d.y<320)==true)//停车got
          {
             fill(255,255,0);
             display_stop();
             myPort.write('S');//指令
             myPort.write(0);//X轴命令
             myPort.write(0);//Y轴命令
             println("STOP");
          }
           if((p2d.x>20)&&(p2d.x<213)&&(p2d.y>160)&&(p2d.y<320)==true)//原地左转got
             {
               fill(173,255,147);
               display_left();
               value_x=map(p2d.x,20.0,213.0,255.0,1.0);
               value_x_=int(value_x);
               myPort.write('L');//指令
               myPort.write(value_x_);//X轴命令
               myPort.write(0);//Y轴命令
               print("GO--LEFT  ");
               println(value_x_);
            }
           if((p2d.x>426)&&(p2d.x<620)&&(p2d.y>160)&&(p2d.y<320)==true)//原地右转got
             {
               fill(173,255,47);
               display_right();
               value_x=map(p2d.x,426.0,620.0,1.0,255.0);
               value_x_=int(value_x);
               myPort.write('R');//指令
               myPort.write(value_x_);//X轴命令
               myPort.write(0);//Y轴命令
               print("GO--RIGHT  ");
               println(value_x_);
             }
          if((p2d.x>213)&&(p2d.x<426)&&(p2d.y>20)&&(p2d.y<160)==true)//前进got
            {  
               fill(50,205,50);
               display_forward();
               value_y=map(p2d.y,20.0,160.0,255.0,1.0);
               value_y_=int(value_y);
               myPort.write('F');//指令
               myPort.write(0);//X轴命令
               myPort.write(value_y_);//Y轴命令
               print("GO--FORWARD  ");
               println(value_y_);
            }
          if((p2d.x>213)&&(p2d.x<426)&&(p2d.y>320)&&(p2d.y<460)==true)//后退got
            {
               fill(50,205,50);
               display_back();
               value_y=map(p2d.y,320.0,460.0,1.0,255.0);
               value_y_=int(value_y);
               myPort.write('B');//指令
               myPort.write(0);//X轴命令
               myPort.write(value_y_);//Y轴命令
               print("GO--BACK  ");
               println(value_y_);
            }
          if((p2d.x>20)&&(p2d.x<213)&&(p2d.y>20)&&(p2d.y<160)==true)//左前转
            {   
             fill(0,225,225);
             display_forward_left();   
             value_x=map(p2d.x,20.0,213.0,255.0,1.0);
             value_y=map(p2d.y,20.0,160.0,255.0,1.0);
             value_x_=int(value_x);
             value_y_=int(value_y);
             myPort.write('C');
             myPort.write(value_x_);
             myPort.write(value_y_);
             print("GO--LEFT FORWARD");
             print(" X=");
             print(value_x_);
             print(" Y=");
             println(value_y_);
            }
          if((p2d.x>426)&&(p2d.x<620)&&(p2d.y>20)&&(p2d.y<160)==true)//右前转
            {
             fill(0,225,225);
             display_forward_right();
             value_x=map(p2d.x,426.0,620.0,1.0,255.0);
             value_y=map(p2d.y,20.0,160.0,225.0,1.0);
             value_x_=int(value_x);
             value_y_=int(value_y);
             myPort.write('D');
             myPort.write(value_x_);
             myPort.write(value_y_);
             print("GO--RIGHT FORWARD");
             print(" X=");
             print(value_x_);
             print(" Y=");
             println(value_y_);
            }
            if((p2d.x>20)&&(p2d.x<213)&&(p2d.y>320)&&(p2d.y<460)==true)//左后传
            {
              fill(0,225,225);
              display_back_left();
              value_x=map(p2d.x,20.0,213.0,255.0,1.0);
              value_y=map(p2d.y,320.0,460.0,1.0,255.0);
              value_x_=int(value_x);
              value_y_=int(value_y);
              myPort.write('E');
              myPort.write(value_x_);
              myPort.write(value_y_);
              print("GO--LEFT BACK");
              print(" X=");
              print(value_x_);
              print(" Y=");
              println(value_y_);
            }
            if((p2d.x>426)&&(p2d.x<620)&&(p2d.y>320)&&(p2d.y<460)==true)//右后转
            {
              fill(0,225,225);
              display_back_right();
              value_x=map(p2d.x,426.0,620.0,1.0,255.0);
              value_y=map(p2d.y,320.0,460.0,1.0,255.0);
              value_x_=int(value_x);
              value_y_=int(value_y);
              myPort.write('G');
              myPort.write(value_x_);
              myPort.write(value_y_);
              print("GO--RIGHT BACK");
              print(" X=");
              print(value_x_);
              print(" Y=");
              println(value_y_);
            }                 
       else if(p2d.x<20||p2d.x>620||p2d.y<20||p2d.y>460)//边缘命令保护
         {
            myPort.write('S');
            myPort.write(0);
            myPort.write(0);
            println("STOP");
         }         
        stroke(255,0,0);
        strokeWeight(2);
        ellipse(p2d.x,p2d.y,10,10);//圆心
        fill(110,90,10);
        line(p2d.x-10,p2d.y,p2d.x+10,p2d.y);//圆心横
        line(p2d.x,p2d.y-10,p2d.x,p2d.y+10);//圆心竖   
         /************************************************************************/
        /***************************发送指令(以上部分)***************************/
        /************************************************************************/
    }        
  }
}
// -----------------------------------------------------------------
// hand events

void onNewHand(SimpleOpenNI curContext,int handId,PVector pos)
{
  println("onNewHand - handId: " + handId + ", pos: " + pos);

  ArrayList<PVector> vecList = new ArrayList<PVector>();
  vecList.add(pos);
  
  handPathList.put(handId,vecList);
}

void onTrackedHand(SimpleOpenNI curContext,int handId,PVector pos)
{
  //println("onTrackedHand - handId: " + handId + ", pos: " + pos );  
  ArrayList<PVector> vecList = handPathList.get(handId);
  if(vecList != null)
  {
    vecList.add(0,pos);
    if(vecList.size() >= handVecListSize)
      // remove the last point
      vecList.remove(vecList.size()-1);
  }  
}
void onLostHand(SimpleOpenNI curContext,int handId)
{
  println("onLostHand - handId: " + handId);
  handPathList.remove(handId);
}
// -----------------------------------------------------------------
// gesture events
void onCompletedGesture(SimpleOpenNI curContext,int gestureType, PVector pos)
{
  println("onCompletedGesture - gestureType: " + gestureType + ", pos: " + pos);
  
  int handId = context.startTrackingHand(pos);
  println("hand stracked: " + handId);
}
// -----------------------------------------------------------------
// Keyboard event
void keyPressed()
{
  switch(key)
  {
  case ' ':
    context.setMirror(!context.mirror());
    break;
  case '1':
    context.setMirror(true);
    break;
  case '2':
    context.setMirror(false);
    break;
  }
}
/*****************************************************************************/
/*******************************自定义界面************************************/
/*****************************************************************************/
void line_display()
{
        strokeWeight(3);
        line_();
        display_forward();
        display_back();//后退
        display_left();
        display_right();
        display_stop();
        display_forward_left();
        display_forward_right();
        display_back_left();
        display_back_right();
}
void display_forward()//前进箭头
{
        stroke(50,205,50);
        //fill(50,205,50);
        beginShape();
        vertex(320,30);
        vertex(280,150);
        vertex(360,150);
        vertex(320,30);
        endShape();
}
void display_back()//后退
{
    //后退箭头
        stroke(50,205,50);
        //fill(50,205,50);
        beginShape();
        vertex(320,450);
        vertex(280,330);
        vertex(360,330);
        vertex(320,450);
        endShape();
}
void display_left()
{
         //左转箭头
        stroke(173,255,47);
        //fill(255,20,147);
        beginShape();
        vertex(40,240);
        vertex(160,200);
        vertex(160,280);
        vertex(40,240);
        endShape();
}
void display_right()
{
         //右转箭头
        stroke(173,255,47);
        //fill(255,20,147);
        beginShape();
        vertex(600,240);
        vertex(480,200);
        vertex(480,280);
        vertex(600,240);
        endShape();
      
}
void display_stop()
{
            
        //停止
        stroke(255,255,0);
        //noFill();
        ellipse(320,240,80,80);
        //fill(255,255,0);
        beginShape();
        vertex(330,245);
        vertex(310,245);
        vertex(300,265);
        vertex(310,265);
        vertex(317,251);
        vertex(323,251);
        vertex(330,265);
        vertex(340,265);
        vertex(330,245);
        endShape();
        beginShape();
        vertex(300,239);
        vertex(340,239);
        vertex(346,227);
        vertex(340,227);
        vertex(337,233);
        vertex(303,233);
        vertex(300,227);
        vertex(294,227);
        vertex(300,239);
        endShape();
        beginShape();
        vertex(315,218);
        vertex(315,228);
        vertex(325,228);
        vertex(325,218);//第四个点
        vertex(315,218);
        endShape();
        line(315,218,325,228);
        line(315,228,325,218);      
}
void display_forward_left()
{
        //左前箭头got
        stroke(0,255,255);
        //fill(0,255,255);
        beginShape();
        vertex(56,38);
        vertex(180,84);
        vertex(128,150);
        vertex(56,38);
        endShape();
     
}
void display_forward_right()
{
         //右前箭头got
        stroke(0,255,255);
        //fill(0,255,255);
        beginShape();
        vertex(584,38);
        vertex(460,84);
        vertex(512,150);
        vertex(584,38);
        endShape();
     
}
void display_back_left()
{
           //左后箭头
        stroke(0,255,255);
        //fill(0,255,255);
        beginShape();
        vertex(56,442);
        vertex(180,396);
        vertex(128,330);
        vertex(56,442);
        endShape();
      
}
void display_back_right()
{
          //右后箭头
        stroke(0,255,255);
        //fill(0,255,255);
        beginShape();
        vertex(584,442);
        vertex(460,396);
        vertex(512,330);
        vertex(584,442);
        endShape();
}
void line_()
{
        line(213,20,213,460);//竖线1
        line(426,20,426,460);//竖线2
        line(20,160,620,160);//横线1
        line(20,320,620,320);//横线2
        beginShape();
        vertex(20,20);
        vertex(620,20);
        vertex(620,460);
        vertex(20,460);
        vertex(20,20);
        endShape();
}[/code]      

  1. char value;//接收命令字符变量
  2. int carspeed_x;//接收速度字符变量
  3. int carspeed_y;
  4. int leftA=3;//左电机A
  5. int leftB=4;//左电机B
  6. int rightA=7;//右电机A
  7. int rightB=2;//右电机B
  8. int pwm_A=5;
  9. int pwm_B=6;
  10. void setup()
  11. {
  12.   pinMode(leftA,OUTPUT);
  13.   pinMode(leftB,OUTPUT);
  14.   pinMode(rightA,OUTPUT);
  15.   pinMode(rightB,OUTPUT);
  16.   pinMode(pwm_A,OUTPUT);
  17.   pinMode(pwm_B,OUTPUT);
  18.   Serial.begin(9600);
  19. }
  20. void loop()
  21. {
  22.    if (Serial.available())
  23.    {
  24.        value = Serial.read();//接收指令
  25.        while(!Serial.available());
  26.        carspeed_x=Serial.read();//接收数据
  27.        while(!Serial.available());
  28.        carspeed_y=Serial.read();
  29.        switch(value)
  30.        {
  31.            case  'F': Forward(carspeed_y);break;
  32.            case  'B': Back(carspeed_y);break;
  33.            case  'L': Left_Here(carspeed_x);break;
  34.            case  'R': Right_Here(carspeed_x);break;
  35.            case  'C': Left_Forward(carspeed_x,carspeed_y);break;
  36.            case  'D': Right_Forward(carspeed_x,carspeed_y);break;
  37.            case  'E': Left_Back(carspeed_x,carspeed_y);break;
  38.            case  'G': Right_Back(carspeed_x,carspeed_y);break;
  39.            case  'S': Stop();
  40.            default: break;
  41.        }
  42.    }
  43. }
  44. void Forward(int _speed_1)//前进got
  45.   {
  46.     digitalWrite(leftA,HIGH);
  47.     digitalWrite(leftB,LOW);
  48.     analogWrite(pwm_A,_speed_1);
  49.     digitalWrite(rightA,HIGH);
  50.     digitalWrite(rightB,LOW);
  51.     analogWrite(pwm_B,_speed_1);
  52.   }
  53. void Back(int _speed_2)//后退got
  54.   {
  55.     digitalWrite(leftA,LOW);
  56.     digitalWrite(leftB,HIGH);
  57.     analogWrite(pwm_A,_speed_2);
  58.     digitalWrite(rightA,LOW);
  59.     digitalWrite(rightB,HIGH);
  60.     analogWrite(pwm_B,_speed_2);
  61.   }
  62. void Left_Here(int _speed_3)//原地左转got
  63.   {
  64.     digitalWrite(leftA,HIGH);
  65.     digitalWrite(leftB,LOW);
  66.     analogWrite(pwm_A,_speed_3);
  67.     digitalWrite(rightA,LOW);
  68.     digitalWrite(rightB,HIGH);
  69.     analogWrite(pwm_B,_speed_3);
  70.   }
  71. void Right_Here(int _speed_4)//原地右转got
  72.   {
  73.     digitalWrite(leftA,LOW);
  74.     digitalWrite(leftB,HIGH);
  75.     analogWrite(pwm_A,_speed_4);
  76.     digitalWrite(rightA,HIGH);
  77.     digitalWrite(rightB,LOW);
  78.     analogWrite(pwm_B,_speed_4);
  79.   }
  80. void Left_Forward(int _speed_5_1,int _speed_5_2)//左前转got
  81.   {
  82.     digitalWrite(leftA,HIGH);
  83.     digitalWrite(leftB,LOW);
  84.     analogWrite(pwm_A,255-_speed_5_1);
  85.     digitalWrite(rightA,HIGH);
  86.     digitalWrite(rightB,LOW);
  87.     analogWrite(pwm_B,_speed_5_2);
  88.   }
  89. void Right_Forward(int _speed_6_1,int _speed_6_2 )//右前转got
  90.   {
  91.     digitalWrite(leftA,HIGH);
  92.     digitalWrite(leftB,LOW);
  93.     analogWrite(pwm_A,_speed_6_2);
  94.     digitalWrite(rightA,HIGH);
  95.     digitalWrite(rightB,LOW);
  96.     analogWrite(pwm_B,255-_speed_6_1);
  97.   }
  98. void Left_Back(int _speed_7_1,int _speed_7_2)//左后转got
  99.   {
  100.     digitalWrite(leftA,LOW);
  101.     digitalWrite(leftB,HIGH);
  102.     analogWrite(pwm_A,255-_speed_7_1);
  103.     digitalWrite(rightA,LOW);
  104.     digitalWrite(rightB,HIGH);
  105.     analogWrite(pwm_B,_speed_7_2);
  106.   }
  107. void Right_Back(int _speed_8_1,int _speed_8_2)//右后转got
  108.   {
  109.     digitalWrite(leftA,LOW);
  110.     digitalWrite(leftB,HIGH);
  111.     analogWrite(pwm_A,_speed_8_2);
  112.     digitalWrite(rightA,LOW);
  113.     digitalWrite(rightB,HIGH);
  114.     analogWrite(pwm_B,255-_speed_8_1);
  115.   }
  116. void Stop()//停车got
  117.   {
  118.     digitalWrite(leftA,LOW);
  119.     digitalWrite(leftB,LOW);
  120.     analogWrite(pwm_A,0);
  121.     digitalWrite(rightA,LOW);
  122.     digitalWrite(rightB,LOW);
  123.     analogWrite(pwm_B,0);
  124.   }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2014-8-24 01:02:59 | 显示全部楼层
……………………
回复 支持 反对

使用道具 举报

发表于 2014-8-24 09:21:56 | 显示全部楼层
这个的确不错,比我的手机控制的wifirobot要精密的多,
手动指挥小车给女友送个花,碉堡了
回复 支持 反对

使用道具 举报

发表于 2014-8-24 09:22:57 | 显示全部楼层
搂着的车体也是用了,arduino +L298N的架构,实现四驱动
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-8-24 09:30:47 | 显示全部楼层
潇洒哥 发表于 2014-8-24 09:21
这个的确不错,比我的手机控制的wifirobot要精密的多,
手动指挥小车给女友送个花,碉堡了

这个车还没成型,暑假后加上机械臂,打算重力传感器控制臂弯,弯曲传感器控制抓取
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-8-24 09:33:37 | 显示全部楼层
潇洒哥 发表于 2014-8-24 09:21
这个的确不错,比我的手机控制的wifirobot要精密的多,
手动指挥小车给女友送个花,碉堡了

手机控制方便多了,用kinect炫一点,就是预算大
回复 支持 反对

使用道具 举报

发表于 2014-8-24 16:49:14 | 显示全部楼层
这年头玩4轴的真多,我看见了是NAZA飞控~~
期待楼主的视频
回复 支持 反对

使用道具 举报

发表于 2014-8-24 21:41:53 | 显示全部楼层
不错不错  呵呵
回复 支持 反对

使用道具 举报

发表于 2014-8-24 22:23:51 | 显示全部楼层
kinect这个要几千吧?
回复 支持 反对

使用道具 举报

发表于 2014-8-24 23:20:17 | 显示全部楼层
万马奔腾 发表于 2014-8-24 22:23
kinect这个要几千吧?

用不着,才600左右。
回复 支持 反对

使用道具 举报

发表于 2014-8-25 11:44:16 | 显示全部楼层
期待做得更牛逼,直接使用普通的webcam
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-2 21:33:23 | 显示全部楼层
本帖最后由 小智 于 2014-9-2 21:41 编辑
软件-蹄飞 发表于 2014-8-24 16:49
这年头玩4轴的真多,我看见了是NAZA飞控~~
期待楼主的视频


http://v.youku.com/v_show/id_XNzcxMTg4MzI4.html这是视屏的链接,做的有些粗糙
回复 支持 反对

使用道具 举报

发表于 2014-9-4 14:05:56 | 显示全部楼层
小智 发表于 2014-9-2 21:33
http://v.youku.com/v_show/id_XNzcxMTg4MzI4.html这是视屏的链接,做的有些粗糙

听小车的声音,好像好暴力的样子
回复 支持 反对

使用道具 举报

发表于 2014-9-28 07:55:43 | 显示全部楼层
我也好想做kinect啊,怎样实现与Arduino的交互啊? 有kinect的代码可以共享吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-28 22:22:35 | 显示全部楼层
ggg781959574 发表于 2014-9-28 07:55
我也好想做kinect啊,怎样实现与Arduino的交互啊? 有kinect的代码可以共享吗?

kinect交互是通过processing与arduino交互的,arduino的代码都在帖子里
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-25 06:03 , Processed in 0.052948 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表