相關(guān)商品
【創(chuàng)客學(xué)堂】Arduino與Kinect打造“體感智能車”
編輯:Jacky2013-08-19 瀏覽次數(shù):2950
體感智能車的原理非常的簡單,就是利用Kinect采集人體的姿體信息,然后通過藍(lán)牙串口向Arduino發(fā)送字符命令。Arduino通過相應(yīng)的字符命令控制雙H橋電機(jī)驅(qū)動模塊實現(xiàn)小車的前進(jìn)后退等動作。項目主要用到的產(chǎn)品由哈爾濱奧松機(jī)器人科技有限公司(下文簡稱“奧松”)提供用到的產(chǎn)品如下圖:
Arduino實現(xiàn)串口控制小車
下面按照制作過程為大家介紹如何來弄。
一、安裝4WD小車,在這里為大家推薦奧松的4WD小車,小車是純金屬的外殼比較抗撞不容易損壞。(安裝視頻 http://v.youku.com/v_show/id_XNTU2NjY3MDI0.html)
安裝好小車地盤后再小車地盤內(nèi)部安裝雙H橋驅(qū)動和電池將控制引腳用3P杜邦線接到Arduino上,連接好電源向Arduino內(nèi)燒錄程序(編譯軟件為Arduino IDE)。代碼如下:
#define pinI1 9 //定義I1接口
#define pinI2 8 //定義I2接口
#define speedpin 10 //定義EA(PWM調(diào)速)接口
#define pinI3 4 //定義I3接口
#define pinI4 5 //定義I4接口
#define speedpin1 6 //定義EB(PWM調(diào)速)接口
#define SPEED 150
char opt = ' ' ;
void setup()
{
Serial.begin(115200);
pinMode(pinI1,OUTPUT); //初始化電機(jī)控制引腳為輸出
pinMode(pinI2,OUTPUT);
pinMode(speedpin,OUTPUT);
pinMode(pinI3,OUTPUT); //初始化電機(jī)控制引腳為輸出
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();
}
//直行函數(shù)time為直行的時間 單位ms
void Straight(int time)
{
analogWrite(speedpin,SPEED);//輸入模擬值進(jìn)行設(shè)定速度
analogWrite(speedpin1,SPEED);
digitalWrite(pinI4,HIGH);//使直流電機(jī)(右)逆時針轉(zhuǎn)
digitalWrite(pinI3,LOW);
digitalWrite(pinI1,HIGH);//使直流電機(jī)(左)順時針轉(zhuǎn)
digitalWrite(pinI2,LOW);
delay(time);
}
//右轉(zhuǎn)函數(shù)time為直行的時間 單位ms
void youzhuan(int time)
{
analogWrite(speedpin,SPEED);//輸入模擬值進(jìn)行設(shè)定速度
analogWrite(speedpin1,SPEED);
digitalWrite(pinI4,HIGH);//使直流電機(jī)(右)逆時針轉(zhuǎn)
digitalWrite(pinI3,LOW);
digitalWrite(pinI1,LOW);//使直流電機(jī)(左)順時針轉(zhuǎn)
digitalWrite(pinI2,HIGH);
delay(time);
}
//左轉(zhuǎn)函數(shù)time為直行的時間 單位ms
void zuozhuan(int time)
{
analogWrite(speedpin,SPEED);//輸入模擬值進(jìn)行設(shè)定速度
analogWrite(speedpin1,SPEED);
digitalWrite(pinI4,LOW);//使直流電機(jī)(右)逆時針轉(zhuǎn)
digitalWrite(pinI3,HIGH);
digitalWrite(pinI1,HIGH);//使直流電機(jī)(左)順時針轉(zhuǎn)
digitalWrite(pinI2,LOW);
delay(time);
}
//后退函數(shù)time為后退的時間 單位ms
void Retreat(int time)
{
analogWrite(speedpin,SPEED);//輸入模擬值進(jìn)行設(shè)定速度
analogWrite(speedpin1,SPEED);
digitalWrite(pinI4,LOW );//使直流電機(jī)(右)順時針轉(zhuǎn)
digitalWrite(pinI3,HIGH);
digitalWrite(pinI1,LOW);//使直流電機(jī)(左)逆時針轉(zhuǎn)
digitalWrite(pinI2,HIGH);
delay(time);
}
//剎車函數(shù)time為停車的時間 單位ms
void Stop(int time)
{
digitalWrite(pinI4,HIGH);//使直流電機(jī)(右)剎車
digitalWrite(pinI3,HIGH);
digitalWrite(pinI1,HIGH);//使直流電機(jī)(左)剎車
digitalWrite(pinI2,HIGH);
delay(time);
}
程序下載好后安裝藍(lán)牙模塊,通過串口助手進(jìn)行測試,確定字符命令可以控制小車。
Kinect與Arduino進(jìn)行串口通信
下面進(jìn)行Kinect的代碼編寫,我采用的是processing軟件,使用前需要安裝Kinectqu驅(qū)動”OpenNI_NITE_Installer-win32-0.27“和kinect的鏈接庫”SimpleOpenNI-0.27“(下載地址 https://code.google.com/p/simple-openni/downloads/list)。
解壓驅(qū)動包,首先安裝OpenNI,然后安裝SensorKinect,最后Sensor全部安裝完成以后,重啟電腦。將你的Kinect連接上電腦插好電源,可以通過查看控制面板中的設(shè)備管理器,檢查你的電腦是否已 經(jīng)識別Kinect。
驅(qū)動安裝完成后下載processing軟件雙擊打開,打開后會在”我的文檔“中出現(xiàn)processing文件夾講下載的庫文件”SimpleOpenNI-0.27“解壓后復(fù)制到processing下的libraries下如果沒有新建一個即可。重新打開processing就可以進(jìn)行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 = "哈爾濱奧松機(jī)器人科技有限公司";
Str_w = "前進(jìn)";
Str_s = "后退";
Str_a = "左轉(zhuǎn)";
Str_d = "右轉(zhuǎn)";
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://m.lifestyle201.com/goods-142.html
processing與arduino互動套件http://m.lifestyle201.com/goods-210.html
用戶評價
- 咨詢內(nèi)容:
- 你好,想問一下藍(lán)牙模塊是怎樣安裝的?
- 管理員:
-
尊敬的客戶您好,感謝您對奧松機(jī)器人的支持和厚愛,藍(lán)牙模塊使用資料:http://m.lifestyle201.com/wiki/index.php/SKU:RB-03T008A_藍(lán)牙_4.0_模塊,如未解決,可以點擊網(wǎng)站右側(cè)小奧頭像聯(lián)系在線QQ客服
- 咨詢內(nèi)容:
- 你好,能不能給我發(fā)一分,OpenNI和SimpleOpenNI-0.27的安裝包,下載不成。跪謝??!
- 管理員:
-
您好,感謝您對我們的支持,我們會繼續(xù)努力上架更多更好的產(chǎn)品,請您及時關(guān)注我們的平臺。這款產(chǎn)品是官方原裝進(jìn)口的,所以庫存要即時查詢,您有需要可以聯(lián)系我們的在線客服,我們的工作時間為8:30-17:30.如果您有更多問題,請關(guān)注我們官方論壇:www.makerspace.cn,會有更多詳細(xì)的解答和更多學(xué)習(xí)的機(jī)會。