ウェアハウスの配布
1。はじめに
電子商取引の出現により、製品の需要が高まり、企業は大量の在庫を必要とし、日常的に大量の処理を行う必要があります。これには、保管、移動、スキャン、検査、配送など、多くの労働集約的なタスクが含まれます。効率を高めるために、需要に基づいて、半自律システムから完全自律システムまで、さまざまな程度で自動化に移行する倉庫および配送センターの数が増えています。
ロボット処理システムは、さまざまな需要要件を柔軟に管理でき、24時間年中無休で機能するため、倉庫や配送センターでますます使用されています。
このプロジェクトでは、ロボットアームを使用して、コンベヤーからパッケージを転送し、それを社内の輸送ボットに積み込んで保管します。
II。動作中
これは自動化されたピックアップおよび輸送システムであり、2自由度のロボットアーム(図に表示)
2 )z軸とx軸を中心に回転でき、グリッパーが付いています。輸送ボット(
に表示)図1 )ドッキングステーションからの距離を検出するために、超音波センサーが取り付けられています。駅に近づくと、車両は180度回転し、アームに到着を知らせる通知を送信します。受信時に、アームは最初にz軸に位置合わせされ、コンベヤーに向かって90度回転し、グリッパーの助けを借りてコンベヤーから貨物をピックアップします。貨物を拾うと、アームは-90度回転し、z軸(グリッパーが上を向く)に戻ります。次に、OpenCVとPiCameraを使用して輸送車両を検索するときに、アームがz軸を中心に回転を開始します。コンベヤーの反対側に配置されている輸送ボットを検出すると、アームはさらにアームをボットに向かって-90度回転させ、xを中心にピックアップボットの上にグリッパーを配置します。その後、グリッパーが開いて貨物をボットに配置し、初期位置に戻るときに、同じ場所に(Bluetooth)信号を送信して積載を示します。輸送車両はこの通知を受け取ると、ドッキングステーションから目的の保管場所に向かって移動を開始します。
III。ローパスフィルター
ローパスバターワースフィルターを使用して、カメラの読み取りx-y-zデータの高周波変化をフィルターで除去しました。 x-y-z値からベクトルを作成し、このフィルターを適用しています。フィルタを適用した後、ノイズを減らしてグラフを滑らかにするために、ベクトルの最後の20要素の平均値を取得します。これにより、PiCamからボールのより正確な位置を取得します。
図3 、オレンジ色の線は生データ(非常にノイズが多く変動が大きい)で、青い線は滑らかなフィルター処理されたバタです。
IV。エレクトロニクス
サーボ: プロジェクトでは合計5つのサーボモーターが使用されています。輸送車両を運転するための2(ディファレンシャルドライブ)。 3は、ロボットアームの関節を制御するために使用されます。
超音波センサー: 超音波センサーは、超音波を使用して物体までの距離を測定します。センサー内の送信機は、一定の間隔で短い高周波の音のパルスを放出します。このパルスは空中で伝播し、物体に当たるとエコー信号として受信機に反射されます。距離は、信号を発信してからエコーを受信するまでの時間(飛行時間と呼ばれます)を測定することによって計算されます。移動ロボットに搭載され、経路計画と検出に使用されますBluetooth:Arduinoに搭載されたHC06は、Raspberrypiの内蔵Bluetoothモジュールとシリアル通信するために使用されます。
Pi-Camera:ロボットアームのジョイントの1つに取り付けられたカメラを使用して、ドッキングステーションのどこかに配置された輸送車両を追跡します。
V。回路
図でわかるように 4 ラズベリーパイでは3つのサーボを使用しました。
Raspberry piにはPWMピンが2つしかないため、3つのサーボを実行するための独自のPWMサーボコードを作成しました。
上記のように、パイカムはラズベリーパイに取り付けられています。カメラはOpenCVを使用してボールを見つけ、腕の位置をロックします。
上図に示すように、Arduinoには合計4つのコンポーネントが接続されています。 2つのサーボ、1つの超音波センサー、および1つのHC-06Bluetoothモジュール。カーゴボットの実行にはどちらを使用しますか?
V。 コード
VI.I. Arduinoコード:
#include
サーボが残っています;
サーボ権;
const int GNND =4; const int GNDD =35; const int echo =37; const int trig =39; const int VCCC =41;
float invcmCosnt =(2 * 1000000)/(100 * 344.8); // cmDist =rawTime / invcmCosnt void setup(){
Serial.begin(9600); Serial3.begin(9600);
left.attach(3); //ピン9のサーボをサーボオブジェクトright.attach(5);
に接続しますpinMode(trig、OUTPUT); pinMode(echo、INPUT); pinMode(GNND、OUTPUT); pinMode(GNDD、OUTPUT); pinMode(VCCC、OUTPUT);
digitalWrite(VCCC、HIGH); digitalWrite(GNND、LOW); digitalWrite(GNDD、LOW); pinMode(LED_BUILTIN、OUTPUT);
left.write(114); right.write(74);
}
void loop(){
float rawTime、cmDist; digitalWrite(trig、LOW); delayMicroseconds(2); digitalWrite(trig、HIGH); delayMicroseconds(5); digitalWrite(trig、LOW); rawTime =pulseIn(echo、HIGH); cmDist =100;
while(cmDist> 4){digitalWrite(trig、LOW); delayMicroseconds(2); digitalWrite(trig、HIGH); delayMicroseconds(5); digitalWrite(trig、LOW); rawTime =pulseIn(echo、HIGH); cmDist =rawTime / invcmCosnt; Serial.println(cmDist);
}
Serial.println( "Out"); Serial3.println( "s"); left.write(94); right.write(94); delay(1000); left.write(114); right.write(114); delay(1700); Serial.println( "Turned"); left.write(94); right.write(94); Serial.println( "停止"); while(1){
if(Serial3.read()==’f’){break;
}
}
left.write(114); right.write(74); delay(2500); left.write(94); right.write(94); while(1){
}
}
VI.II.ラズベリー
Raspberryの最後で、最初に見つけるには、次のコマンドを使用してRaspberryPiをHC-06Bluetoothモジュールに接続する必要があります。
$ hcitool scan#BluetoothのMAC IDがわかっていて利用できる場合は、スキップできます
次に、適切なMAC IDを使用して必要なBluetoothに接続します:
$ sudo rfcomm connect hci0 xx:xx:xx:xx:xx:xx
これが正常に実行されると、Bluetoothが接続されます。
コレクションから必要なパッケージをインポートしますimportdeque
from imutils.video import VideoStream import numpy as np
import argparse import cv2 import imutils import time import timeit
from scipy import signal import matplotlib.pyplot as plt
RPi.GPIOをGPIOとしてインポート
シリアルのインポート
GPIO.setmode(GPIO.BCM)GPIO.setup(12、GPIO.OUT)#グリッパーGPIO.setup(13、GPIO.OUT)#Rot_x GPIO.setup(16、GPIO.OUT)#Rot_z
rotz =16
rotx =GPIO.PWM(13、50)gr =GPIO.PWM(12、50)
blue =serial.Serial(“ / dev / rfcomm0”、baudrate =9600)print(“ Bluetooth接続”)
defduty(角度):
戻り角度* 5/90 + 2.5
def search(angle =90、add =1):servo_pwm(rotz、duty(angle)、50)ap =argparse.ArgumentParser()ap.add_argument(“-v”、“ –video”、
help =”(オプションの)ビデオファイルへのパス”)ap.add_argument(“-b”、“ –buffer”、type =int、default =64、
help =” max buffer size”)args =vars(ap .parse_args())
xn =np.zeros([500])xm =np.zeros([1])
greenLower =(20、20、53)
greenUpper =(64 、255、255)
pts =deque(maxlen =args [“ buffer”])
ビデオパスが指定されていない場合は、Webカメラへの参照番号を取得します
args.get(“ video”、False)でない場合:
vs =VideoStream(src =0).start()
それ以外の場合は、ビデオファイルへの参照を取得します。else:
vs =cv2.VideoCapture(args [“ video”])
カメラまたはビデオファイルがtime.sleep(2.0)
をウォームアップできるようにします
Trueの場合:
if angle ==125:
add =-5
elif angle ==35:
add =5 angle + =add
servo_pwm(rotz、デューティ(角度)、10)time.sleep(0.01)
現在のフレームフレームを取得=vs.read()
VideoCaptureまたはVideoStreamからのフレームを処理しますframe =frame [1] if args.get( "video"、False)else frame
ビデオを視聴していて、フレームを取得しなかった場合は、#ビデオの最後に到達しました
フレームがNoneの場合:
break
フレームのサイズを変更し、ぼかして、HSV#カラースペースに変換します
frame =imutils.resize(frame、width =600)blured =cv2.GaussianBlur(frame、(11、11)、0)
hsv =cv2.cvtColor(blurred、cv2.COLOR_BGR2HSV)
「緑」の色のマスクを作成し、#一連の拡張と侵食を実行して、マスクに残っている小さなブロブを#削除します
mask =cv2.inRange(hsv、greenLower、greenUpper)mask =cv2.erode(mask、None、iterations =2)
mask =cv2.dilate(mask、None、iterations =2)
マスク内の輪郭を見つけて、ボールの現在の#(x、y)中心を初期化します
cnts =cv2.findContours(mask.copy()、cv2.RETR_EXTERNAL、cv2.CHAIN_APPROX_SIMPLE)
cnts =imutils.grab_contours(cnts)center =なし
len(cnts)> 0の場合に少なくとも1つの輪郭が見つかった場合にのみ続行します:
マスクで最大の輪郭を見つけて、
を使用します最小の囲み円と#重心を計算します
c =max(cnts、key =cv2.contourArea)
((x、y)、radius)=cv2.minEnclosingCircle(c)M =cv2.moments(c)
center =(int(M [“ m10”] / M [“ m00”])、int(M [“ m01”] / M [“ m00”]))#半径が最小サイズに一致する場合にのみ続行
半径> 10の場合:
フレームに円と図心を描画し、#次に追跡ポイントのリストを更新しますcv2.circle(frame、(int(x)、int(y))、int(radius)、
(0、255、255)、2)
cv2.circle(frame、center、5、(0、0、255)、-1)
xn =np.delete(xn、0)xn =np.append(xn、x)fs =300
fc =1 x_old =x
w =fc /(fs / 2)
b、a =signal.butter(5、w、 'low')output =signal.filtfilt(b、a、xn)x =np.average(xn [480:500])print(x、x_old)
xm =np.append(xm、x)if abs(x – 300)<20:
break
ポイントキューを更新しますpts.appendleft(center)
for i in range(1、len(pts)):
追跡されたポイントのいずれかがNoneの場合、#それらを無視します
pts [i – 1]がNoneの場合、またはpts [i]がNoneの場合:
続行
それ以外の場合は、線の太さを計算し、#接続線を描画します
厚さ=int(np.sqrt(args [“ buffer”] / float(i + 1))* 2.5)cv2.line(frame、pts [i – 1]、pts [i]、(0、0、255) 、厚さ)
画面にフレームを表示しますcv2.imshow( "Frame"、frame)key =cv2.waitKey(1)&0xFF
「q」キーが押された場合、key ==ord( "q")の場合はループを停止します:
print(xn)print(xn.shape)plt.plot(xm、label =’x’)plt.show()
break
args.get( "video"、False)でない場合:vs.stop()
それ以外の場合は、カメラを放します。
vs.release()
すべてのウィンドウを閉じますcv2.destroyAllWindows()return x、add
defservo_pwm(pin、duty、pulse):on =20 * Duty / 100000
off =-on + 20/1000 for i in range(pulse):
GPIO.output(pin、GPIO.HIGH )time.sleep(on)GPIO.output(pin、GPIO.LOW)time.sleep(off)
def Grip(angle =90):
servo_pwm(rotz、duty(angle)、100)rotx.start(duty(90))gr.start(duty(100))
time.sleep(1 )rotx.ChangeDutyCycle(duty(0))time.sleep(1)gr.ChangeDutyCycle(duty(180))time.sleep(0.5)rotx.ChangeDutyCycle(duty(90))time.sleep(0.5)
def drop():rotx.ChangeDutyCycle(duty(180))
time.sleep(1)gr.ChangeDutyCycle(duty(100))time.sleep(1)rotx.ChangeDutyCycle(duty(90))time.sleep(0.5)
def done():
done =“ f”
done =done.encode()blue.write(done)
try:
while True:
data =blue.readline()#data =data.decode()
print(type(data)、data)#if data!=“ s”:
print(“ did n’t”)#続行
else:print( "found s")grip(80)
x、add =search(80、5)drop()
done()
KeyboardInterruptを除く:GPIO.cleanup()print( "Quit")
VII。結論
このプロジェクトでは、倉庫自動化のための荷役システムを実装しました。ロボットアームがコンベヤーベルトから商品を拾い上げ、搭載されたカメラを使用して輸送車両を検索し、注文を車両にロードします。その後、輸送車両は商品を必要な場所に運び、さらに処理します。倉庫の自動化は、顧客の需要の高まりと電子商取引の成長により、大企業と中小企業の両方でますます一般的になっています。 Goods to People(GTP)は、商品が労働者からアイテムに移動するのではなく、労働者に移動するという新しいトレンドです。 Bastian SolutionsInc。のアソシエイトコンサルティングエンジニアであるNathanBusch氏は、次のように述べています。「GTPシステムのスループット率は、通常、従来の手動操作よりもかなり高くなっています。これにより、企業はスループットとサービスレベルを向上させながら、全体的な運用コストと注文処理コストを削減できます。」アイテムが検索され、ピックアップされ、それぞれの処理サイトに運ばれるため、モバイルロボティクスは今やこの重要な部分になっています。このプロジェクトの将来の範囲は、完全に自律的な倉庫システムで広く検討されました。このシステムでは、保管されるアイテムを別のシステムで分離でき、上記のシステムで商品をコンベヤーから在庫ボットに転送できます。希望の保管場所への最適なパスと商品の在庫。このデモンストレーションは、前述のシステムを中小企業の利益のために部分的に実装できることを示しています。したがって、手動操作とロボット操作を組み合わせて、スループットを向上させ、パフォーマンスを向上させます。
出典:WEARHOUSE DISTRIBUTION
製造プロセス