基于Leap motion的手势移动机器人控制.docx
- 文档编号:28040811
- 上传时间:2023-07-07
- 格式:DOCX
- 页数:25
- 大小:23.80KB
基于Leap motion的手势移动机器人控制.docx
《基于Leap motion的手势移动机器人控制.docx》由会员分享,可在线阅读,更多相关《基于Leap motion的手势移动机器人控制.docx(25页珍藏版)》请在冰豆网上搜索。
基于Leapmotion的手势移动机器人控制
基于Leapmotion的手势移动机器人控制
简介(Introduction)
设计题目:
基于Leapmotion的手势移动机器人控制。
开发环境(SoftwareDevelopmentEnvironment):
Arduino,VisualStudio2013。
硬件平台:
Leapmotion,HCR移动机器人(控制器:
ArduinoMega2560,电机:
12V直流减速电机146rpm)。
1本周内容(Section1)
功能实现分为以下五部分:
1.Leapmotion识别手势信息。
利用Leapmotion现有的例程,识别几个简单的手势信息(点击、滑动、顺时针或逆时针旋转)。
2.自定义头文件,将Leapmotion识别到的几个手势信息定义为我们所需要的指令。
(这里我们是将点击定义为“W”即小车向前移动命令,将滑动定义为“S”即小车向后移动命令,将顺时针或逆时针旋转定义为“A”或“D”即小车左转或右转命令。
)
3.将我们所使用的Leapmotion例程和自定义头文件程序发送到控制小车的串口。
我们这时可以通过串口调试助手来观察串口收发指令的情况。
4.将下位机程序烧入小车控制器,这里我们所使用的是ArduinoMega2560集成开发板(基于AVR单片机)。
5.利用手势来控制小车的移动,达到简单的人机交互的目的。
2总结(Conclusion)
3.1所遇到的问题:
1.手势控制只能进行一次。
即只有第一次的手势信息有效,能够达到控制小车的目的。
但后面的手势虽能通过串口助手监测到,但无法实现控制小车的目的?
可能的原因:
1)串口只能执行接受到的第一条指令。
2)缺少中断和循环程序。
2.Leapmotion手势识别程序编写难度大,所牵扯到的工程项目多,目前还不能自己编写Leapmotion手势识别程序,只能找相关的例程(C++程序)。
3.不要忽略了Leapmotion环境配置这里步骤,未配置好环境会导致在程序调试的过程中出现诸多的错误。
Leapmotion环境配置后就可以将Leapmotion手势识别程序加到串口通信程序中(注意.dll文件的添加)。
3.2总结:
本次设计,用到了简单的人机交互方面的知识,即通过实验者的手势来达到控制小车移动的目的。
其核心的技术是如何识别手势信息(Leapmotion),这其中牵扯到很多高深的算法,这里不得不佩服微软的开发人员。
后面就是如何把识别到的手势信息转化为我们需要的指令和下位机程序。
通过这次设计,我对人机交互有了一个大概的了解,也在实践方面收获了很多。
4.附录
1)手势识别程序(4个手势)+串口通信程序:
2)#include
3)#include
4)#include
5)#include"Leap.h"
6)DWORDdwLength;
7)charrecvBuf[1024];
8)DWORDdwactlen;
9)charbacks[8]="s";
10)charforwardw[8]="w";
11)charlefta[8]="a";
12)charrightd[8]="d";
13)DCBmyDCB;
14)HANDLEm_hComm;
15)usingnamespaceLeap;
16)classSampleListener:
publicListener{
17)public:
18)virtualvoidonInit(constController&);
19)virtualvoidonConnect(constController&);
20)virtualvoidonDisconnect(constController&);
21)virtualvoidonExit(constController&);
22)virtualvoidonFrame(constController&);
23)virtualvoidonFocusGained(constController&);
24)virtualvoidonFocusLost(constController&);
25)};
26)voidSampleListener:
:
onInit(constController&controller){
27)std:
:
cout<<"Initialized"< : endl; 28)} 29) 30)voidSampleListener: : onConnect(constController&controller){ 31)std: : cout<<"Connected"< : endl; 32)controller.enableGesture(Gesture: : TYPE_CIRCLE); 33)controller.enableGesture(Gesture: : TYPE_KEY_TAP); 34)controller.enableGesture(Gesture: : TYPE_SCREEN_TAP); 35)controller.enableGesture(Gesture: : TYPE_SWIPE); 36)} 37) 38)voidSampleListener: : onDisconnect(constController&controller){ 39)//Note: notdispatchedwhenrunninginadebugger. 40)std: : cout<<"Disconnected"< : endl; 41)} 42) 43)voidSampleListener: : onExit(constController&controller){ 44)std: : cout<<"Exited"< : endl; 45)} 46) 47)voidSampleListener: : onFrame(constController&controller){ 48)//Getthemostrecentframeandreportsomebasicinformation 49)constFrameframe=controller.frame(); 50)std: : cout<<"Frameid: "< 51)<<",timestamp: "< 52)<<",hands: "< 53)<<",fingers: "< 54)<<",tools: "< 55)<<",gestures: "< : endl; 56) 57)if(! frame.hands().empty()){ 58)//Getthefirsthand 59)constHandhand=frame.hands()[0]; 60) 61)//Checkifthehandhasanyfingers 62)constFingerListfingers=hand.fingers(); 63)if(! fingers.empty()){ 64)//Calculatethehand'saveragefingertipposition 65)VectoravgPos; 66)for(inti=0;i 67)avgPos+=fingers[i].tipPosition(); 68)} 69)avgPos/=(float)fingers.count(); 70)std: : cout<<"Handhas"< 71)<<"fingers,averagefingertipposition"< : endl; 72)} 73) 74)//Getthehand'ssphereradiusandpalmposition 75)std: : cout<<"Handsphereradius: "< 76)<<"mm,palmposition: "< : endl; 77) 78)//Getthehand'snormalvectoranddirection 79)constVectornormal=hand.palmNormal(); 80)constVectordirection=hand.direction(); 81) 82)//Calculatethehand'spitch,roll,andyawangles 83)std: : cout<<"Handpitch: "< 84)<<"roll: "< 85)<<"yaw: "< : endl; 86)} 87) 88)//Getgestures 89)constGestureListgestures=frame.gestures(); 90)for(intg=0;g 91)Gesturegesture=gestures[g]; 92) 93)switch(gesture.type()){ 94)caseGesture: : TYPE_CIRCLE: 95){ 96)CircleGesturecircle=gesture; 97)std: : stringclockwiseness; 98) 99)if(circle.pointable().direction().angleTo(circle.normal())<=PI/4){ 100)clockwiseness="clockwise"; 101) 102)if(WriteFile(m_hComm,lefta,8,&dwactlen,NULL)) 103){ 104)printf("writesuccess! \n"); 105)} 106)else 107){ 108)printf("writefailed! \n"); 109)} 110)} 111)else{ 112)clockwiseness="counterclockwise"; 113) 114)if(WriteFile(m_hComm,rightd,8,&dwactlen,NULL)) 115){ 116)printf("writesuccess! \n"); 117)} 118)else 119){ 120)printf("writefailed! \n"); 121)} 122)} 123) 124)//Calculateanglesweptsincelastframe 125)floatsweptAngle=0; 126)if(circle.state()! =Gesture: : STATE_START){ 127)CircleGesturepreviousUpdate=CircleGesture(controller.frame (1).gesture(circle.id())); 128)sweptAngle=(circle.progress()-previousUpdate.progress())*2*PI; 129)} 130)std: : cout<<"Circleid: "< 131)<<",state: "< 132)<<",progress: "< 133)<<",radius: "< 134)<<",angle"< 135)<<","< : endl; 136)break; 137)} 138)caseGesture: : TYPE_SWIPE: 139){ 140)SwipeGestureswipe=gesture; 141)std: : cout<<"swipe"< : endl; 142)break; 143)} 144)caseGesture: : TYPE_KEY_TAP: 145){ 146)KeyTapGesturetap=gesture; 147)std: : cout<<"KeyTapid: "< 148)<<",state: "< 149)<<",position: "< 150)<<",direction: "< : endl; 151) 152)if(WriteFile(m_hComm,backs,8,&dwactlen,NULL)) 153){ 154)printf("writesuccess! \n"); 155)} 156)else 157){ 158)printf("writefailed! \n"); 159)} 160)break; 161)} 162)caseGesture: : TYPE_SCREEN_TAP: 163){ 164)ScreenTapGesturescreentap=gesture; 165)std: : cout<<"ScreenTapid: "< 166)<<",state: "< 167)<<",position: "< 168)<<",direction: "< : endl; 169)if(WriteFile(m_hComm,forwardw,8,&dwactlen,NULL)) 170){ 171)printf("writesuccess! \n"); 172)} 173)else 174){ 175)printf("writefailed! \n"); 176)} 177)break; 178)} 179)default: 180)std: : cout<<"Unknowngesturetype."< : endl; 181)break; 182)} 183)} 184) 185)if(! frame.hands().empty()||! gestures.empty()){ 186)std: : cout< : endl; 187)} 188)} 189) 190)voidSampleListener: : onFocusGained(constController&controller){ 191)std: : cout<<"FocusGained"< : endl; 192)} 193) 194)voidSampleListener: : onFocusLost(constController&controller){ 195)std: : cout<<"FocusLost"< : endl; 196)} 197) 198)intmain() 199){ 200) 201)m_hComm=CreateFile( 202)"COM3: ", 203)GENERIC_READ|GENERIC_WRITE,//允许读和写 204)0,//独占方式(共享模式) 205)NULL, 206)OPEN_EXISTING,//打开而不是创建(创建方式) 207)0, 208)NULL 209)); 210) 211)//得到打开串口的当前属性参数,修改后再重新设置串口。 212) 213)if(! GetCommState(m_hComm,&myDCB)) 214){ 215)printf("GetCommStateerror"); 216)returnFALSE; 217)} 218) 219)//设置串口参数 220)myDCB.BaudRate=CBR_19200;//设置波特率19200 221)myDCB.fBinary=TRUE;//设置二进制模式,此处必须设置TRUE 222)myDCB.fParity=TRUE;//支持奇偶校验 223)myDCB.fOutxCtsFlow=FALSE;//NoCTSoutputflowcontrol 224)myDCB.fOutxDsrFlow=FALSE;//NoDSRoutputflowcontrol 225)myDCB.fDtrControl=DTR_CONTROL_DISABLE;//NoDTRflowcontrol 226)myDCB.fDsrSensitivity=FALSE;//DSRsensitivity 227)myDCB.fTXContinueOnXoff=TRUE;//XOFFcontinuesTx 228)myDCB.fOutX=FALSE;//NoXON/XOFFoutflowcontrol 229)myDCB.fInX=FALSE;//NoXON/XOFFinflowcontrol 230)myDCB.fErrorChar=FALSE;//Disableerrorreplacement 231)myDCB.fNull=FALSE;//Disablenullstripping 232)myDCB.fRtsControl=RTS_CONTROL_DISABLE;//NoRTSflowcontrol 233)myDCB.fAbortOnError=FALSE;//当串口发生错误,并不终止串口读写 234)myDCB.ByteSize=8;//数据位,范围: 4-8 235)myDCB.Parity=NOPARITY;//校验模式 236)myDCB.StopBits=0;//1位停止位 237)//设置串口参数 238)if(! SetCommState(m_hComm,&myDCB)) 239){ 240)printf("SetCommStateerror"); 241)returnFALSE; 242)} 243)//Createasamplelistenerandcontroller 244)SampleListenerlistener; 245)Controllercontroller; 246) 247)//Havethesamplelistenerreceiveeventsfromthecontroller 248)controller.addListener(listener); 249) 250)//KeepthisprocessrunninguntilEnterispressed 251)std: : cout<<"PressEntertoquit..."< : endl; 252)std: : cin.get(); 253)//Removethesamplelistenerwhendone 254)controller.removeListener(listener); 255)CloseHandle(m_hComm);//m_hComm是CreateFile函数返回的串口句柄。 256)return0; 257)} 2)移动小车控制程序(编译环境Arduino,控制器ArduinoMega2560) intE1=5;//M1速度控制 intE2=6;//M2速度控制 intM1=4;//M1方向控制 intM2=7;//
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于Leap motion的手势移动机器人控制 基于 Leap motion 手势 移动 机器人 控制