相关商品

  • Arduino Due ARM控制器 Arduino原装进口 32bit CortexM3
  • Pololu m3pi 机器人 迷宫 机器人小车 Pololu原装 进口机器人小车
  • Arduino Starter Kit Arduino入门套件 意大利中国代理
  • Arduino Yun Arduino官方原装 Arduino Yún WiFi Linux
  • Arduino无线SD扩展板 Arduino原装进口
  • Arduino Ethernet w/o PoE Arduino原装进口 arduino网络扩展板
  • Arduino UNO R3 SMD 控制器 ATmega16U2 开发版 单片机 sparkfun原装进口
  • PicoBoard互动创新板(单板非套件) 传感器互动板 Scratch教学传感板
  • PVCBOT零基础机器人制作配书套件 小学生DIY模型科技小制作套装
  • PVCBOT零基础机器人制作教材  DIY机器人配书套件 科技小制作小发明
  • PVCBOT零基础机器人制作工具包 五金焊接电子模型玩具工具箱套装
  • ArduPilot 固定翼 飞控 多旋翼 Arduino 控制器 Sparkfun原装进口
  • Arduino 双路大功率直流电机驱动扩展板 VNH5019 美国Pololu原装
  • Arduino 直流电机驱动板 MiniMoto DRV8830 IIC/I2C Sparkfun原装
  • Arduino 机器人权威指南 爱上Arduino制作指南
  • Arduino 模拟传感器 Slider Sensor 直滑电位计 位置 滑动传感器
  • Arduino Intel Galileo Gen 2 伽利略开发板 官方授权
  • 当前位置: 首页 > 应用教程 > 【创客学堂】Arduino与Kinect打造“体感智能车”

    【创客学堂】Arduino与Kinect打造“体感智能车”

    编辑:Jacky2013-08-19 浏览次数:2921

            体感智能车的原理非常的简单,就是利用Kinect采集人体的姿体信息,然后通过蓝牙串口向Arduino发送字符命令。Arduino通过相应的字符命令控制双H桥电机驱动模块实现小车的前进后退等动作。项目主要用到的产品由哈尔滨奥松机器人科技有限公司(下文简称“奥松”)提供用到的产品如下图:

    Kinect+Arduino

     

    Arduino实现串口控制小车

         

    下面按照制作过程为大家介绍如何来弄。

    一、安装4WD小车,在这里为大家推荐奥松的4WD小车,小车是纯金属的外壳比较抗撞不容易损坏。(安装视频  http://v.youku.com/v_show/id_XNTU2NjY3MDI0.html)

    4WD小车

    4WD小车

          安装好小车地盘后再小车地盘内部安装双H桥驱动和电池将控制引脚用3P杜邦线接到Arduino上,连接好电源向Arduino内烧录程序(编译软件为Arduino IDE)。代码如下:

    #define  pinI1  9      //定义I1接口

    #define  pinI2  8      //定义I2接口

    #define  speedpin 10   //定义EA(PWM调速)接口

     #define  pinI3  4      //定义I3接口

    #define  pinI4  5      //定义I4接口

    #define  speedpin1 6   //定义EB(PWM调速)接口 

    #define SPEED    150 

    char opt = ' ' ; 

    void setup()

    {  

      Serial.begin(115200);

      pinMode(pinI1,OUTPUT);       //初始化电机控制引脚为输出

      pinMode(pinI2,OUTPUT);

      pinMode(speedpin,OUTPUT);

      

      pinMode(pinI3,OUTPUT);       //初始化电机控制引脚为输出

      pinMode(pinI4,OUTPUT);

      pinMode(speedpin1,OUTPUT);

    }

     

     

    void loop()

    {

        while(Serial.available()>0)

          opt = Serial.read();

      

        switch(opt)

        {

          case 'w':

            Straight(200);

            break;

          case 'a':

            zuozhuan(200);

            break;

          case 's':

            Retreat(200);

            break;

          case 'd':

            youzhuan(200);

            break;

          case 'x':

            Stop(200);

            break;

         case 'q':

            Straight(200);

            delay(1000);

            zuozhuan(200);

            delay(500);

             Straight(200);

            delay(1000);

            youzhuan(200);

            delay(500);

            Stop(200);

            opt = -1;

           break;

          default:

           break;

        }

        Serial.flush();

    }

     

      

     //直行函数time为直行的时间  单位ms

     void Straight(int time)

     {

         analogWrite(speedpin,SPEED);//输入模拟值进行设定速度

         analogWrite(speedpin1,SPEED);

         

         digitalWrite(pinI4,HIGH);//使直流电机(右)逆时针转

         digitalWrite(pinI3,LOW);

         

         digitalWrite(pinI1,HIGH);//使直流电机(左)顺时针转

         digitalWrite(pinI2,LOW);     

         delay(time);

     }

     

      //右转函数time为直行的时间  单位ms

     void youzhuan(int time)

     {

         analogWrite(speedpin,SPEED);//输入模拟值进行设定速度

         analogWrite(speedpin1,SPEED);

         

         digitalWrite(pinI4,HIGH);//使直流电机(右)逆时针转

         digitalWrite(pinI3,LOW);

         

         digitalWrite(pinI1,LOW);//使直流电机(左)顺时针转

         digitalWrite(pinI2,HIGH);     

         delay(time);

     }

     

      //左转函数time为直行的时间  单位ms

     void zuozhuan(int time)

     {

         analogWrite(speedpin,SPEED);//输入模拟值进行设定速度

         analogWrite(speedpin1,SPEED);

         

         digitalWrite(pinI4,LOW);//使直流电机(右)逆时针转

         digitalWrite(pinI3,HIGH);

         

         digitalWrite(pinI1,HIGH);//使直流电机(左)顺时针转

         digitalWrite(pinI2,LOW);     

         delay(time);

     }

     

     //后退函数time为后退的时间  单位ms

     void Retreat(int time)

     {

         analogWrite(speedpin,SPEED);//输入模拟值进行设定速度

         analogWrite(speedpin1,SPEED);

         

         digitalWrite(pinI4,LOW );//使直流电机(右)顺时针转

         digitalWrite(pinI3,HIGH);

         

         digitalWrite(pinI1,LOW);//使直流电机(左)逆时针转

         digitalWrite(pinI2,HIGH);

     

         delay(time);

     }

     

     

    //刹车函数time为停车的时间  单位ms

     void Stop(int time)

     {

         digitalWrite(pinI4,HIGH);//使直流电机(右)刹车

         digitalWrite(pinI3,HIGH);

         

         digitalWrite(pinI1,HIGH);//使直流电机(左)刹车

         digitalWrite(pinI2,HIGH);

         delay(time);

     

     }

    4WD小车

     

            程序下载好后安装蓝牙模块,通过串口助手进行测试,确定字符命令可以控制小车。

    Kinect与Arduino进行串口通信

            下面进行Kinect的代码编写,我采用的是processing软件,使用前需要安装Kinectqu驱动”OpenNI_NITE_Installer-win32-0.27“和kinect的链接库”SimpleOpenNI-0.27“(下载地址 https://code.google.com/p/simple-openni/downloads/list)。

     

             解压驱动包,首先安装OpenNI,然后安装SensorKinect,最后Sensor全部安装完成以后,重启电脑。将你的Kinect连接上电脑插好电源,可以通过查看控制面板中的设备管理器,检查你的电脑是否已 经识别Kinect

     

    Kinect

              驱动安装完成后下载processing软件双击打开,打开后会在”我的文档“中出现processing文件夹讲下载的库文件”SimpleOpenNI-0.27“解压后复制到processing下的libraries下如果没有新建一个即可。重新打开processing就可以进行Kenect的程序编写了。

              控制小车的代码如下:

    import SimpleOpenNI.*;

    SimpleOpenNI  kinect;

     

    import processing.serial.*;

    Serial port;

     

    PFont myFont;

    String myStr;

    String Str_w;

    String Str_s;

    String Str_a;

    String Str_d;

    String Str_x;

    String Str_temp_NO;

    String Str_temp_Yes;

     

    PVector right_hand;

    PVector right_hip;

     

    PVector head;

     

    PVector left_hand;

    PVector left_hip;

     

    PVector difference;

    float   shouju;

    float   youtou;

    float   zuotou;

    float   youhip;

    float   zuohip;

     

    char ch_w= 'w';

    char ch_s= 's';

    char ch_a= 'a';

    char ch_d= 'd';

    char ch_x= 'x';

     

    void setup() 

    {

      size(640, 600);   

      kinect = new SimpleOpenNI(this); 

      kinect.enableDepth(); 

      kinect.enableRGB();  

      kinect.setMirror(true);  

      kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL); 

      

      myFont = createFont("黑体", 32); 

      myStr = "哈尔滨奥松机器人科技有限公司"; 

      Str_w = "前进";

      Str_s = "后退";

      Str_a = "左转";

      Str_d = "右转";

      Str_x = "停止"; 

      Str_temp_NO = "未识别";

      Str_temp_Yes = "连接成功";

      

      right_hand = new PVector();

      right_hip = new PVector();

     

      head = new PVector();

     

      left_hand = new PVector();

      left_hip = new PVector();

      

      println(Serial.list());

      String portName = Serial.list()[0];

      port = new Serial(this, portName, 115200);

    }

     

    void draw() 

      background(80,100,140);//

      kinect.update();

      

      //PImage depthImage = kinect.depthImage();

      //image(kinect.depthImage(),0, 0);  

      PImage rgbImage = kinect.rgbImage();  

      image(rgbImage, 0, 0); 

      

      fill(0,0,255); 

      textFont(myFont); 

      text(myStr, 100, 530);   

      text("www.robotbase.cn" , 195, 565);

       

      IntVector userList = new IntVector();

      kinect.getUsers(userList);

     

      if (userList.size() > 0)

      {

        int userId = userList.get(0);

        onEndCalibration(userId, true);

     

        if ( kinect.isTrackingSkeleton(userId))

        {

            fill(0,0,255);

            textFont(myFont); 

            text(myStr, 100, 530);   

            text("www.robotbase.cn" , 195, 565);

            

            fill(0, 255, 0);

            textSize(25);

            text(Str_temp_Yes, 270,30);

            

            kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_RIGHT_HAND,right_hand);

            kinect.convertRealWorldToProjective(right_hand, right_hand);

          

            kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_RIGHT_HIP,right_hip);

            kinect.convertRealWorldToProjective(right_hip, right_hip);

                

            kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_HEAD,head);

            kinect.convertRealWorldToProjective(head, head);

            

            kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_LEFT_HAND,left_hand);

            kinect.convertRealWorldToProjective(left_hand, left_hand);

                  

            kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_LEFT_HIP,left_hip);

            kinect.convertRealWorldToProjective(left_hip, left_hip);

            

           //textSize(20);

            difference = PVector.sub(right_hand, left_hand);

            shouju = difference.mag();

           // text("shouju: " + int(shouju), 20, 20);

            

            difference = PVector.sub(right_hand, head);

            youtou = difference.mag();

          //  text("youtou: " + int(youtou), 20, 45);

            

            difference = PVector.sub(left_hand, head);

            zuotou = difference.mag();

          //  text("zuotou: " + int(zuotou), 20, 70);

            

            difference = PVector.sub(right_hand, right_hip);

            youhip = difference.mag();

          //  text("youhip: " + int(youhip), 20, 95);

            

            difference = PVector.sub(left_hand, right_hip);

            zuohip = difference.mag();

          //  text("zuohip: " + int(zuohip), 20, 120); 

            

            fill(255, 255, 0);

            textSize(20);

            if(shouju>400 && youtou>200 && zuotou>200 && youhip>200 && zuohip>200)

            {

              text(Str_w, 20, 40);

              port.write(ch_w);

            }

            else if(shouju<200 && youtou<200 && zuotou<200 && youhip>200 && zuohip>200)

            {

              text(Str_s, 20, 40);

              port.write(ch_s); 

            }

            else if(shouju>300 && youtou>180 && zuotou>180 && youhip<150 && zuohip>250)

            {

              text(Str_a, 20, 40);

              port.write(ch_a); 

            }

            else if(shouju>300 && youtou>180 && zuotou>180 && youhip>200 && zuohip<150)

            {

              text(Str_d, 20, 40);

              port.write(ch_d); 

            }

            else if(shouju<250 && youtou>180 && zuotou>180 && youhip<180 && zuohip<180)

            {

              text(Str_x, 20, 40);

              port.write(ch_x); 

            }        

            /***************************************************************

            fill(255, 0, 0);

            ellipse(left_hip.x, left_hip.y, 15, 15);

            ellipse(left_hand.x, left_hand.y, 15, 15);

            ellipse(head.x, head.y, 15, 15);

            ellipse(right_hip.x, right_hip.y, 15, 15);

            ellipse(right_hand.x, right_hand.y, 15, 15);

            ****************************************************************/

            /****************************************************************

            stroke(0, 255, 0);

            strokeWeight(4);

            line(right_hand.x, right_hand.y, head.x, head.y);

            line(right_hand.x, right_hand.y, right_hip.x, right_hip.y);

            line(left_hand.x, left_hand.y, head.x, head.y);

            line(left_hand.x, left_hand.y, left_hip.x, left_hip.y);

            ****************************************************************/

        }

      }

      else

      {

          fill(255, 0, 0);

          textSize(25);

          text(Str_temp_NO, 280, 30);

      }

    }

     

    // user-tracking callbacks!

    void onNewUser(int userId) {

      println("start pose detection");

      kinect.startPoseDetection("Psi", userId);

    }

    void onEndCalibration(int userId, boolean successful) {

      if (successful) {

        println("  User calibrated !!!");

        kinect.startTrackingSkeleton(userId);

      }

      else {

        println("  Failed to calibrate user !!!");

        kinect.startPoseDetection("Psi", userId);

      }

    }

    void onStartPose(String pose, int userId) {

      println("Started pose for user");

      kinect.stopPoseDetection(userId);

      kinect.requestCalibrationSkeleton(userId, true);

    }

            程序编写完成后连接蓝牙串口(注意没有串口时程序会报错)这样一个体感智能车就制作完成了。操作视频如下:
     
     
     

      Arduino MEGA 1280 控制器 http://www.alsrobot.cn/goods-142.html

      processing与arduino互动套件http://www.alsrobot.cn/goods-210.html 

    • 用户评价

    qq570873165144
    咨询内容:
    你好,想问一下蓝牙模块是怎样安装的?

    管理员:
    尊敬的客户您好,感谢您对奥松机器人的支持和厚爱,蓝牙模块使用资料:http://www.alsrobot.cn/wiki/index.php/SKU:RB-03T008A_蓝牙_4.0_模块,如未解决,可以点击网站右侧小奥头像联系在线QQ客服
    匿名用户
    咨询内容:
    你好,能不能给我发一分,OpenNI和SimpleOpenNI-0.27的安装包,下载不成。跪谢!!
    管理员:
    您好,感谢您对我们的支持,我们会继续努力上架更多更好的产品,请您及时关注我们的平台。这款产品是官方原装进口的,所以库存要即时查询,您有需要可以联系我们的在线客服,我们的工作时间为8:30-17:30.如果您有更多问题,请关注我们官方论坛:www.makerspace.cn,会有更多详细的解答和更多学习的机会。
    总计 2 个记录,共 1 页。 第一页 上一页 下一页 最末页
    用户名: 匿名用户
    E-mail:
    评价等级:
    评论内容:
    验证码:
    captcha

    Hi,大家好,我是小奥!

    欢迎来到奥松机器人的世界!

    需要咨询服务请点小奥哦!

    • 销售咨询: 销售咨询
    • 销售咨询: 销售咨询
    • 技术支持: 技术支持
    • 咨询电话:
      0451-86628691
    Top