本帖最后由 小智 于 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]
- char value;//接收命令字符变量
- int carspeed_x;//接收速度字符变量
- int carspeed_y;
- int leftA=3;//左电机A
- int leftB=4;//左电机B
- int rightA=7;//右电机A
- int rightB=2;//右电机B
- int pwm_A=5;
- int pwm_B=6;
- void setup()
- {
- pinMode(leftA,OUTPUT);
- pinMode(leftB,OUTPUT);
- pinMode(rightA,OUTPUT);
- pinMode(rightB,OUTPUT);
- pinMode(pwm_A,OUTPUT);
- pinMode(pwm_B,OUTPUT);
- Serial.begin(9600);
- }
- void loop()
- {
- if (Serial.available())
- {
- value = Serial.read();//接收指令
- while(!Serial.available());
- carspeed_x=Serial.read();//接收数据
- while(!Serial.available());
- carspeed_y=Serial.read();
- switch(value)
- {
- case 'F': Forward(carspeed_y);break;
- case 'B': Back(carspeed_y);break;
- case 'L': Left_Here(carspeed_x);break;
- case 'R': Right_Here(carspeed_x);break;
- case 'C': Left_Forward(carspeed_x,carspeed_y);break;
- case 'D': Right_Forward(carspeed_x,carspeed_y);break;
- case 'E': Left_Back(carspeed_x,carspeed_y);break;
- case 'G': Right_Back(carspeed_x,carspeed_y);break;
- case 'S': Stop();
- default: break;
- }
- }
- }
- void Forward(int _speed_1)//前进got
- {
- digitalWrite(leftA,HIGH);
- digitalWrite(leftB,LOW);
- analogWrite(pwm_A,_speed_1);
- digitalWrite(rightA,HIGH);
- digitalWrite(rightB,LOW);
- analogWrite(pwm_B,_speed_1);
- }
- void Back(int _speed_2)//后退got
- {
- digitalWrite(leftA,LOW);
- digitalWrite(leftB,HIGH);
- analogWrite(pwm_A,_speed_2);
- digitalWrite(rightA,LOW);
- digitalWrite(rightB,HIGH);
- analogWrite(pwm_B,_speed_2);
- }
- void Left_Here(int _speed_3)//原地左转got
- {
- digitalWrite(leftA,HIGH);
- digitalWrite(leftB,LOW);
- analogWrite(pwm_A,_speed_3);
- digitalWrite(rightA,LOW);
- digitalWrite(rightB,HIGH);
- analogWrite(pwm_B,_speed_3);
- }
- void Right_Here(int _speed_4)//原地右转got
- {
- digitalWrite(leftA,LOW);
- digitalWrite(leftB,HIGH);
- analogWrite(pwm_A,_speed_4);
- digitalWrite(rightA,HIGH);
- digitalWrite(rightB,LOW);
- analogWrite(pwm_B,_speed_4);
- }
- void Left_Forward(int _speed_5_1,int _speed_5_2)//左前转got
- {
- digitalWrite(leftA,HIGH);
- digitalWrite(leftB,LOW);
- analogWrite(pwm_A,255-_speed_5_1);
- digitalWrite(rightA,HIGH);
- digitalWrite(rightB,LOW);
- analogWrite(pwm_B,_speed_5_2);
- }
- void Right_Forward(int _speed_6_1,int _speed_6_2 )//右前转got
- {
- digitalWrite(leftA,HIGH);
- digitalWrite(leftB,LOW);
- analogWrite(pwm_A,_speed_6_2);
- digitalWrite(rightA,HIGH);
- digitalWrite(rightB,LOW);
- analogWrite(pwm_B,255-_speed_6_1);
- }
- void Left_Back(int _speed_7_1,int _speed_7_2)//左后转got
- {
- digitalWrite(leftA,LOW);
- digitalWrite(leftB,HIGH);
- analogWrite(pwm_A,255-_speed_7_1);
- digitalWrite(rightA,LOW);
- digitalWrite(rightB,HIGH);
- analogWrite(pwm_B,_speed_7_2);
- }
- void Right_Back(int _speed_8_1,int _speed_8_2)//右后转got
- {
- digitalWrite(leftA,LOW);
- digitalWrite(leftB,HIGH);
- analogWrite(pwm_A,_speed_8_2);
- digitalWrite(rightA,LOW);
- digitalWrite(rightB,HIGH);
- analogWrite(pwm_B,255-_speed_8_1);
- }
- void Stop()//停车got
- {
- digitalWrite(leftA,LOW);
- digitalWrite(leftB,LOW);
- analogWrite(pwm_A,0);
- digitalWrite(rightA,LOW);
- digitalWrite(rightB,LOW);
- analogWrite(pwm_B,0);
- }
复制代码 |