步調(diào)1:硬件
那是我之前用來構(gòu)建的這個(gè)。我利用來自的部件和我躺正在屋子周圍的器材100%構(gòu)建它。
PhidgetsBoards,Motors,Hardware
HUB0000-VINTHubPhidget
1108-磁傳感器
2xSTC1001-2.5AStepperPhidget
2x3324-42STH38NEMA-17雙極無齒輪步進(jìn)器
3x3002-Phidget電纜60厘米
3403-4端口集線器
3031-母尾5.5
3029-2線100‘絞線
3604-10mm紅色LED
其他部件
24VDC2.0A電源
車庫(kù)廢木跟金屬
拉鏈
底部堵截的塑料容器
第2步:計(jì)劃?rùn)C(jī)器人
咱們須要計(jì)劃一些可以從輸入料斗中掏出一個(gè)珠子,將其放在收集攝像頭下,然后將其挪動(dòng)到得當(dāng)?shù)南渥又械钠鞑摹?/p>
珠子皮卡
我決意用2片圓形膠合板做第1部門,每一個(gè)膠合板正在同一個(gè)處所鉆一個(gè)洞。底部件流動(dòng),頂部件毗鄰到步進(jìn)機(jī)電,步進(jìn)機(jī)電可以正在裝有珠子的料斗下方扭轉(zhuǎn)。當(dāng)孔正在料斗下挪動(dòng)時(shí),它會(huì)拾取一個(gè)珠子。然后我可以正在收集攝像頭下扭轉(zhuǎn)它,然后進(jìn)一步扭轉(zhuǎn),直到它與底部的孔婚配,此時(shí)它便會(huì)落下。
正在這張圖片中,我正在測(cè)試體系能行得通。一切都是流動(dòng)的,除頂部的圓形膠合板,它與上面的步進(jìn)機(jī)電相連。收集攝像頭還沒有裝置。我此刻只是利用Phidget控制面板轉(zhuǎn)向機(jī)電。
珠子存儲(chǔ)
下一部分是計(jì)劃用于連結(jié)每種顏色的bin體系。我決意利用上面的第二個(gè)步進(jìn)機(jī)電去支持跟扭轉(zhuǎn)存在平均距離隔間的圓形容器。那可以用來扭轉(zhuǎn)珠子將從此中失落出的孔下方的精確隔間。
我利用紙板跟膠帶去構(gòu)建它。這里最緊張的是一致性-每一個(gè)隔間該當(dāng)是不異的尺寸,全部器材該當(dāng)平均減輕,以便扭轉(zhuǎn)而不會(huì)跳過。
經(jīng)由過程慎密貼合的蓋子實(shí)現(xiàn)珠子的移除一次只有一個(gè)隔間,以是可以倒出珠子。
收集攝像頭裝置正在料斗跟下板孔地位之間的頂板上。那容許體系正在掉落之前窺察珠子。LED用于照亮相機(jī)下方的珠子,而且環(huán)境光被阻攔,以供給同等的照明情況。那關(guān)于精確的顏色檢測(cè)十分緊張,由于環(huán)境光可以真正天消弭感知顏色。
地位檢測(cè)
體系可能檢測(cè)到珠子的扭轉(zhuǎn)十分緊張分開器。那用于正在啟動(dòng)時(shí)設(shè)置初始地位,但也用于檢測(cè)步進(jìn)機(jī)電是不是曾經(jīng)沒有同步。正在我的體系中,一個(gè)珠子有時(shí)會(huì)正在拾取時(shí)卡住,體系須要可能檢測(cè)并處置懲罰這類環(huán)境-經(jīng)由過程備份跟測(cè)驗(yàn)考試agian。
有良多方式可以處置懲罰這個(gè)(工作。我決意利用1108磁傳感器,正在頂板的邊緣嵌入磁鐵。那容許我驗(yàn)證每次扭轉(zhuǎn)的地位。一個(gè)更好的解決方案能夠是步進(jìn)機(jī)電上的編碼器,但我有一個(gè)1108擺布,以是我利用它。
實(shí)現(xiàn)機(jī)器人
此時(shí),所有皆曾經(jīng)實(shí)現(xiàn)出來,并測(cè)試。此刻是時(shí)間裝置好一切器材并轉(zhuǎn)向編寫軟件。
2個(gè)步進(jìn)機(jī)電由STC1001步進(jìn)控制器驅(qū)動(dòng)。HUB000-USBVINT集線器用于運(yùn)轉(zhuǎn)步進(jìn)控制器,和讀取磁傳感器跟驅(qū)動(dòng)LED。收集攝像頭跟HUB0000皆毗鄰到一個(gè)小型USB集線器。利用3031引線跟一些電線和24V電源為機(jī)電供電。
步調(diào)3:編寫代碼
C#跟VisualStudio2015用于此名目。下載本頁(yè)頂部的源代碼并依照步調(diào)停止操縱-次要部門概述以下
初始化
起首,咱們必需創(chuàng)立,翻開跟初始化Phidget工具。那是正在表單加載事宜跟Phidget附加處理程序中實(shí)現(xiàn)的。
privatevoidForm1_Load(objectsender,EventArgse){
/*InitializeandopenPhidgets*/
=0;
+=Top_Attach;
+=Top_Detach;
+=Top_PositionChange;
;
=1;
+=Bottom_Attach;
+=Bottom_Detach;
+=Bottom_PositionChange;
;
=2;
=true;
+=MagSensor_Attach;
+=MagSensor_Detach;
+=MagSensor_SensorChange;
;
=5;
=true;
=0;
+=Led_Attach;
+=Led_Detach;
;
}
privatevoidLed_Attach(objectsender,e){
=true;
=true;
=true;
}
privatevoidMagSensor_Attach(objectsender,e){
=true;
=_1108;
=16;
}
privatevoidBottom_Attach(objectsender,e){
=true;
=bottomCurrentLimit;
=true;
=bottomVelocityLimit;
=bottomAccel;
=100;
}
privatevoidTop_Attach(objectsender,e){
=true;
=topCurrentLimit;
=true;
=-1;
=-topVelocityLimit;
=-topAccel;
=100;
}
咱們借正在初始化時(shí)代讀取任何已保留的顏色信息,是以可以繼承之前的運(yùn)轉(zhuǎn)。
機(jī)電定位
機(jī)電處置懲罰代碼包羅用于挪動(dòng)機(jī)電的便當(dāng)功用。我利用的機(jī)電每轉(zhuǎn)3,2001/16步,以是我為此創(chuàng)立了一個(gè)常量。
關(guān)于頂部機(jī)電,咱們?cè)竿赡軐?個(gè)地位發(fā)送到機(jī)電:收集攝像頭,孔跟定位磁鐵。有一個(gè)功用可以達(dá)到每一個(gè)地位:
privatevoidnextMagnet(Booleanwait=false){
doubleposn=%stepsPerRev;
+=(stepsPerRev-posn);
if
while;
}
privatevoidnextCamera(Booleanwait=false){
doubleposn=%stepsPerRev;
if
+=;
else
+=+stepsPerRev);
if
while;
}
privatevoidnextHole(Booleanwait=false){
doubleposn=%stepsPerRev;
if
+=;
else
+=+stepsPerRev);
if
while;
}
正在開始運(yùn)行之前,利用磁傳感器對(duì)齊頂板??梢噪S時(shí)挪用alignMotor函數(shù)去對(duì)齊頂板。該功用起首快捷將板遷移轉(zhuǎn)變至1轉(zhuǎn),直至其磁鐵數(shù)據(jù)高于閾值。然后它略微前進(jìn)一點(diǎn)并逐步向前挪動(dòng),捕獲傳感器數(shù)據(jù)。最初,它將地位設(shè)置為最大磁鐵數(shù)據(jù)地位,并將地位偏移重置為0.是以,最大磁鐵地位應(yīng)一直為
ThreadalignMotorThread;
BooleansawMagnet;
doublemagSensorMax=0;
privatevoidalignMotor{
//Findthemagnet
=;
sawMagnet=false;
+=magSensorStopMotor;
=-1000;
inttryCount=0;
tryagain:
+=stepsPerRev;
while
;
if{
if{
;
=false;
=false;
runtest=false;
return;
}
tryCount++;
(“Arewestuck?Tryingabackup.。.”);
-=600;
while;
gototryagain;
}
=-100;
magData=newList》;
+=magSensorCollectPositionData;
+=300;
while;
-=magSensorCollectPositionData;
=-topVelocityLimit;
KeyValuePairmax=magData[0];
foreach(KeyValuePairpairinmagData)
食品分揀機(jī)器人直營(yíng)if
max=pair;
;
magSensorMax=;
=0;
while;
(“Alignsucceeded”);
}
List》magData;
privatevoidmagSensorCollectPositionData(objectsender,e){
(newKeyValuePair;
}
privatevoidmagSensorStopMotor(objectsender,e){
if{
=-300;
-=magSensorStopMotor;
sawMagnet=true;
}
}
最初,經(jīng)由過程將底部馬達(dá)發(fā)送到此中一個(gè)胎圈容器地位去節(jié)制底部馬達(dá)。關(guān)于這個(gè)名目,咱們有19個(gè)職位。算法取舍最短門路,順時(shí)針或逆時(shí)針遷移轉(zhuǎn)變。
privateintBottomPosition{
get{
intposn=%stepsPerRev;
if
posn+=stepsPerRev;
return(((posn*beadCompartments)/stepsPerRev));
}
}
privatevoidSetBottomPosition(intposn,boolwait=false){
posn=posn%beadCompartments;
doubletargetPosn=(posn*stepsPerRev)/beadCompartments;
doublecurrentPosn=%stepsPerRev;
doubleposnDiff=targetPosn-currentPosn;
//Keepitasfullsteps
posnDiff=*16;
if(posnDiff《=1600)
+=posnDiff;
else
-=(stepsPerRev-posnDiff);
if
while;
OpenCV用于從收集攝像頭讀取圖象。正在啟動(dòng)主排序線程之前啟動(dòng)相機(jī)線程。該線程不休讀入圖象,利用Mean計(jì)較特定區(qū)域的均勻顏色并更新全局顏色變量。該線程借利用HoughCircles去檢測(cè)珠子或頂板上的孔,以細(xì)化它正在探求顏色檢測(cè)的區(qū)域。閾值跟HoughCircles數(shù)字是經(jīng)由過程重復(fù)實(shí)驗(yàn)肯定的,而且正在很大水平上在于收集攝像頭,光照跟間距。
boolrunVideo=true;
boolvideoRunning=false;
VideoCapturecapture;
ThreadcvThread;
ColordetectedColor;
Booleandetecting=false;
intdetectCnt=0;
privatevoidcvThreadFunction{
videoRunning=false;
capture=newVideoCapture;
using(Windowwindow=newWindow{
Matimage=newMat;
Matimage2=newMat;
while{
;
if
break;
if
detectCnt++;
else
detectCnt=0;
if(detecting||circleDetectChecked||showDetectionImgChecked){
;
Matthres=;
thres=;
if(showDetectionImgChecked)
image=thres;
if(detecting||circleDetectChecked){
CircleSegment[]bead=(,2,/*/4*/20,200,100,20,65);
if{
快遞分揀機(jī)器人現(xiàn)場(chǎng)(bead[0].Center,3,newScalar;
(bead[0].Center,bead[0].Radius,newScalar;
if(bead[0].Radius》=55){
=bead[0].+(bead[0].Radius/2);
=bead[0].-(bead[0].Radius/2);
}else{
=bead[0].+;
=bead[0].-;
}
=15;
=15;
}else{
CircleSegment[]circles=(,2,/*/4*/5,200,100,60,180);
if{
Listxs=;
;
Listys=;
;
intmedianX=xs[/2];
intmedianY=ys[/2];
if
medianX=-15;
if
medianY=-15;
(medianX,medianY,100,newScalar;
if{
=medianX-7;
=medianY-7;
=15;
=15;
}
}
}
}
}
Rectr=newRect,
,
,
;
MatbeadSample=newMat;
ScalaravgColor=;
detectedColor=avgColor[2],avgColor[1],;
(r,newScalar;
;
;
videoRunning=true;
}
videoRunning=false;
}
}
privatevoidcameraStartBtn_Click(objectsender,EventArgse){
if{
cvThread=newThread(newThreadStart(cvThreadFunction));
runVideo=true;
;
=“stop”;
while
;
}else{
runVideo=false;
;
=“start”;
}
}
顏色
此刻,咱們可以肯定珠子的顏色,并依據(jù)該顏色決意將其放入哪個(gè)容器。
這個(gè)步調(diào)依賴于顏色比力。咱們?cè)竿赡軇澐诸伾韵薅ㄕ`報(bào),但也容許充足的閾值去限定假陽(yáng)性。比力顏色實(shí)際上是非常復(fù)雜的,由于計(jì)算機(jī)將顏色存儲(chǔ)為RGB的方法,和人類感知顏色的方法并不是線性相關(guān)的。更蹩腳的是,借必需思量正在上面窺察顏色的光的顏色。
有龐大的計(jì)較色差的算法。咱們利用CIE2000,若是2種顏色與人類沒法劃分,則輸出瀕臨1的數(shù)字。咱們利用ColorMineC#庫(kù)來實(shí)現(xiàn)這些龐大的計(jì)較。已發(fā)明DeltaE值為5可正在假陽(yáng)性跟假陽(yáng)性之間供給優(yōu)越的調(diào)和。
因?yàn)槿萜髌匠S懈囝伾?,是以最初一個(gè)地位保存為捕捉箱。我平常將這些設(shè)置為第二次經(jīng)由過程機(jī)械。
List
colors=newList
;
List
colorPanels=newList
;
ListcolorsTxts=newList;
ListcolorCnts=newList;
constintnumColorSpots=18;
constintunknownColorIndex=18;
intfindColorPosition{
(“Findingcolor.。.”);
varcRGB=newRgb;
=;
=;
=;
intbestMatch=-1;
doublematchDelta=100;
for(inti=0;i《;i++){
varRGB=newRgb;
=colors[i].R;
=colors[i].G;
=colors[i].B;
doubledelta=(RGB,newCieDe2000Comparison;
//doubledelta=deltaE;
+“):”+;
if(delta《matchDelta){
matchDelta=delta;
bestMatch=i;
}
}
if{
(“Found?。≒osn:”+bestMatch+“Delta:”+matchDelta+“)”);
returnbestMatch;
}
if(《numColorSpots){
;
;
(newAction,newobject[]{-1});
writeOutColors;
return;
}else{
(“UnknownColor!”);
returnunknownColorIndex;
}
}
排序邏輯
排序功能將一切部門搜集正在一路以實(shí)際排序珠子。該函數(shù)正在專用線程中運(yùn)轉(zhuǎn);挪動(dòng)頂板,檢測(cè)珠子顏色,將其放入垃圾箱,確保頂板連結(jié)對(duì)齊,計(jì)數(shù)珠子等。當(dāng)垃圾箱變滿時(shí),它也會(huì)終止運(yùn)轉(zhuǎn)-不然咱們終極會(huì)溢出珠子。
ThreadcolourTestThread;
Booleanruntest=false;
voidcolourTest
=true;
if
=true;
while{
nextMagnet;
;
try{
if(《(magSensorMax-4))
alignMotor;
}catch{alignMotor;}
nextCamera;
detecting=true;
while
;
(“DetectCount:”+detectCnt);
detecting=false;
Colorc=detectedColor;
(newAction
,newobject[]{c});
inti=findColorPosition;
SetBottomPosition;
nextHole;
colorCnts[i]++;
(newAction,newobject[]{i});
;
if(colorCnts[unknownColorIndex]》500){
=false;
=false;
runtest=false;
(newAction,null);
return;
}
自動(dòng)分揀機(jī)器人控制原理藥品分揀機(jī)器人費(fèi)用}
}
privatevoidcolourTestBtn_Click(objectsender,EventArgse){
if(colourTestThread==null||?。﹞
colourTestThread=newThread(newThreadStart;
runtest=true;
;
=“STOP”;
=;
}else{
runtest=false;
=“GO”;
=;
}
}
此時(shí),咱們有一個(gè)事情順序。一些代碼被漏掉正在文章以外,以是看一下實(shí)際運(yùn)轉(zhuǎn)它的源代碼。
分揀機(jī)器人十個(gè)品牌國(guó)產(chǎn)分揀機(jī)器人批發(fā)價(jià)格分揀機(jī)器人的缺點(diǎn)