查看: 9262|回復: 57

[項目] 基于機器視覺的智能分揀機械臂

  [復制鏈接]
  • TA的每日心情
    開心
    2019-3-29 14:36
  • 簽到天數: 9 天

    [LV.3]偶爾看看II

    發表于 2019-3-20 22:28 | 顯示全部樓層 |閱讀模式
    本作品是一個基于機器視覺的智能機械臂操作平臺,采用atmega32單片機作為主控制系統并通過串口與視覺識別模塊進行通訊;控制系統使用12V5A開關電源供電;機械臂是一個六關節機械臂,六個伺服電機分別驅動六個關節轉動,主控制系統控制六個伺服電機實現機械臂空間復雜運動。該智能平臺實現了,對不同大小,顏色,二維碼等目標物品的識別,按指令進行分類、抓取、搬移等動作。


    IMG_20180613_045400 - 副.jpg

    一.  機械臂部分
    IMG_20180612_09254.jpg
    1.材料
    MG996R 996 舵機      *6長U型支架單軸舵機支架 *3
    U型梁                 *2
    S3115通用支架        *5
    L型支架單軸           *1
    金屬 機械手臂 夾持器  *1
    M3螺絲螺母若干                     

    2.組裝
    soogif5.gif soogif7.gif
    soogif8.gif

    soogif9.gif

    soogif10.gif

    soogif1.gif

    soogif2.gif
    soogif3.gif

    soogif4.gif

    3.驅動板
    驅動板用的是申請的KittenBot家的RosBot機器人開發板,圖像化 編程還是很好用的。



    360截圖1646052895128111.png
    4.程序
    游客,如果您要查看本帖隱藏內容請回復

    void setup(){
            Serial.begin(9600);
            kb.init();
            pinMode(A0, INPUT);
            kb.servoArray(2, 160, 10);
            delay(1*1000);
            kb.servoArray(3, 160, 10);
            delay(1*1000);
            kb.servoArray(4, 10, 10);
            delay(1*1000);
            kb.servoArray(5, 90, 5);
            delay(1*1000);
            kb.servoArray(3, 90, 10);
            kb.servoArray(4, 10, 10);
            kb.servoArray(0, 90, 10);
            kb.servoArray(1, 70, 10);
            kb.servoArray(2, 70, 10);
            kb.servoArray(3, 80, 10);
            delay(1*1000);
            kb.servoArray(5, 180, 10);
            delay(3*1000);

    }

    void loop(){
              char val = Serial.read();
            if(val == '1'){
                    delay(1*1000);
                    kb.servoArray(0, 125, 10);
                    delay(1*1000);
                    kb.servoArray(2, 130, 20);
                    kb.servoArray(4, 20, 20);
                    kb.servoArray(5, 145, 5);
                    delay(1*1000);
                    kb.servoArray(1, 160, 20);
                    delay(2*1000);
                    kb.servoArray(0, 100, 20);
                    delay(2*1000);
                    kb.servoArray(4, 10, 10);
                    kb.servoArray(0, 90, 10);
                    kb.servoArray(1, 70, 10);
                    kb.servoArray(2, 70, 10);
                    kb.servoArray(3, 80, 10);
                    delay(1*1000);
                    kb.servoArray(5, 180, 10);
            }
            if(val == '2'){
                    delay(1*1000);
                    kb.servoArray(0, 125, 10);
                    delay(1*1000);
                    kb.servoArray(4, 30, 10);
                    kb.servoArray(3, 135, 10);
                    delay(1*1000);
                    kb.servoArray(5, 130, 10);
                    kb.servoArray(2, 70, 10);
                    delay(1*1000);
                    kb.servoArray(1, 160, 20);
                    delay(2*1000);
                    kb.servoArray(0, 100, 20);
                    delay(2*1000);
                    kb.servoArray(4, 10, 10);
                    kb.servoArray(0, 90, 10);
                    kb.servoArray(1, 70, 10);
                    kb.servoArray(2, 70, 10);
                    kb.servoArray(3, 80, 10);
                    kb.servoArray(5, 180, 10);
            }
            if(val == '3'){
                    delay(1*1000);
                    kb.servoArray(0, 120, 10);
                    delay(1*1000);
                    kb.servoArray(4, 20, 10);
                    kb.servoArray(3, 130, 10);
                    delay(1*1000);
                    kb.servoArray(5, 115, 10);
                    kb.servoArray(2, 55, 10);
                    delay(1*1000);
                    kb.servoArray(1, 160, 20);
                    delay(2*1000);
                    kb.servoArray(0, 100, 20);
                    delay(2*1000);
                    kb.servoArray(4, 10, 10);
                    kb.servoArray(0, 90, 10);
                    kb.servoArray(1, 70, 10);
                    kb.servoArray(2, 70, 10);
                    kb.servoArray(3, 80, 10);
                    kb.servoArray(5, 180, 10);
            }

    }


    二.  傳送帶部分 360截圖16210609324456.png
    1.材料
    35步進電機       *1M8絲桿20cm    *2
    聯軸器5X8         *1
    絲桿固定軸承     *4
    A4紙                  *1  
    A4988驅動板     *1
    ARDUINO PRO MINI  *1
    12V1A電源            *1

    2.驅動電路

    360截圖16240212467072.png


    3.程序

    kittenblock中小學創客名師推薦的圖形化編程軟件

    #include <Servo.h>
    Servo servo1;
    void setup()
    {
      servo1.attach(5);
      Serial.begin(9600);
    }
    void loop()
    {
      int angle = analogRead(A0);
      angle = map(angle, 0, 1023, 0, 180);
      Serial.print("angle = ");
      Serial.println(angle);
      servo1.write(angle);
      delay(15);
    }


    三.  視覺部分
    視覺模塊是參考開源的OPENMV繪制的PCB,采用基于OPENMV的圖像識別模塊,主控為STM32F767,工作頻率可達260MHZ,攝像頭使用0V7725,30W像素。機器視覺識別系統的主控芯片STM32F767通過串口通信方式與主控制系統ATMEGA32單片機傳輸信息

    1.材料
    OPENMV   *1
    2.原理圖
    360截圖166009038110978.png

    3.AprilTag標簽識別原理
    tag36h11_0.png tag36h11_1.png tag36h11_2.png
    AprilTag是一個視覺基準系統,可用于各種任務,包括AR,機器人和相機校準。這個Tag可以直接用打印機打印出來,而AprilTag檢測程序可以計算相對于相機的精確3D位置,方向和ID。在機器人領域有廣泛應用。AprilTag的算法,可以計算出Tag在3維空間中的位置, 與其對應的ID。



    4.顏色識別功能
       顏色識別是通過識別指定物品的色塊,返回色塊的值給主控,主控再根據返回的信息控制機械臂執行相應的動作。



    4.程序
           ①標簽識別

    kittenblock中小學創客名師推薦的圖形化編程軟件

    # AprilTags Example
    #
    # This example shows the power of the OpenMV Cam to detect April Tags
    # on the OpenMV Cam M7. The M4 versions cannot detect April Tags.
    
    import sensor, image, time, math
    
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...
    sensor.skip_frames(time = 2000)
    sensor.set_auto_gain(False)  # must turn this off to prevent image washout...
    sensor.set_auto_whitebal(False)  # must turn this off to prevent image washout...
    clock = time.clock()
    
    # Note! Unlike find_qrcodes the find_apriltags method does not need lens correction on the image to work.
    
    # The apriltag code supports up to 6 tag families which can be processed at the same time.
    # Returned tag objects will have their tag family and id within the tag family.
    
    tag_families = 0
    tag_families |= image.TAG16H5 # comment out to disable this family
    tag_families |= image.TAG25H7 # comment out to disable this family
    tag_families |= image.TAG25H9 # comment out to disable this family
    tag_families |= image.TAG36H10 # comment out to disable this family
    tag_families |= image.TAG36H11 # comment out to disable this family (default family)
    tag_families |= image.ARTOOLKIT # comment out to disable this family
    #print("Tag Family %s, Tag ID %d, rotation %f (degrees)" % print_args)
    #print(clock.fps())
    
    # What's the difference between tag families? Well, for example, the TAG16H5 family is effectively
    # a 4x4 square tag. So, this means it can be seen at a longer distance than a TAG36H11 tag which
    # is a 6x6 square tag. However, the lower H value (H5 versus H11) means that the false positve
    # rate for the 4x4 tag is much, much, much, higher than the 6x6 tag. So, unless you have a
    # reason to use the other tags families just use TAG36H11 which is the default family.
    
    def family_name(tag):
        if(tag.family() == image.TAG16H5):
            return "TAG16H5"
        if(tag.family() == image.TAG25H7):
            return "TAG25H7"
        if(tag.family() == image.TAG25H9):
            return "TAG25H9"
        if(tag.family() == image.TAG36H10):
            return "TAG36H10"
        if(tag.family() == image.TAG36H11):
            return "TAG36H11"
        if(tag.family() == image.ARTOOLKIT):
            return "ARTOOLKIT"
    
    while(True):
        clock.tick()
        img = sensor.snapshot()
        for tag in img.find_apriltags(families=tag_families): # defaults to TAG36H11 without "families".
            img.draw_rectangle(tag.rect(), color = (255, 0, 0))
            img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
            print_args = (family_name(tag), tag.id(), (180 * tag.rotation()) / math.pi)
            print("Tag Family %s, Tag ID %d, rotation %f (degrees)" % print_args)
            print(clock.fps)
    
    

           ②顏色識別

    kittenblock中小學創客名師推薦的圖形化編程軟件

    # Multi Color Blob Tracking Example
    #
    # This example shows off multi color blob tracking using the OpenMV Cam.
    
    import sensor, image, time
    
    # Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max)
    # The below thresholds track in general red/green things. You may wish to tune them...
    thresholds = [(0, 100, 51, 127, -3, 127), # generic_red_thresholds
                  (0, 100, -128, -19, -128, 127), # generic_green_thresholds
                 (39, 100, -63, 13, -128, -16)] # generic_blue_thresholds
    # You may pass up to 16 thresholds above. However, it's not really possible to segment any
    # scene with 16 thresholds before color thresholds start to overlap heavily.
    
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.skip_frames(time = 2000)
    sensor.set_auto_gain(False) # must be turned off for color tracking
    sensor.set_auto_whitebal(False) # must be turned off for color tracking
    clock = time.clock()
    
    # Only blobs that with more pixels than "pixel_threshold" and more area than "area_threshold" are
    # returned by "find_blobs" below. Change "pixels_threshold" and "area_threshold" if you change the
    # camera resolution. Don't set "merge=True" becuase that will merge blobs which we don't want here.
    
    while(True):
        clock.tick()
        img = sensor.snapshot()
        for blob in img.find_blobs(thresholds, pixels_threshold=800, area_threshold=1500):
            img.draw_rectangle(blob.rect(), color = (255, 0, 0))#red
    
            img.draw_string(100,100,'red', color=(255,0,0))
            img.draw_cross(blob.cx(), blob.cy())
       # print(clock.fps())
      #  print(blob.code())
    
    



    五. 總結
    最后總結一下,做這個項目畫了兩個月時間,其中也是花費了很大精力,學到不少東西,整個項目制作,編程,視頻剪輯都是我一人完成。最后,謝謝大家的支持!









    soogif6.gif

    該用戶從未簽到

    發表于 2019-3-21 12:03 | 顯示全部樓層
    干得漂亮! 
  • TA的每日心情
    慵懶
    2019-2-11 19:33
  • 簽到天數: 2 天

    [LV.1]初來乍到

    發表于 2019-4-6 17:20 | 顯示全部樓層
    本帖最后由 Dhgs1026805647 于 2019-4-6 17:21 編輯

    open mv,哈哈

    該用戶從未簽到

    發表于 2019-5-10 15:12 | 顯示全部樓層
    excellent,學習學習
  • TA的每日心情
    開心
    2019-12-1 20:49
  • 簽到天數: 1 天

    [LV.1]初來乍到

    發表于 2019-5-11 19:43 | 顯示全部樓層
    大佬大佬hug:
  • TA的每日心情
    奮斗
    2019-8-19 22:16
  • 簽到天數: 50 天

    [LV.5]常住居民I

    發表于 2019-5-12 10:43 | 顯示全部樓層
    樓主你好,請問你那個openmv也是可以用電腦軟件對其進行編程的嗎?
    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規則

    熱門推薦

    [限時福利]5分鐘帶你快速了解新一代開發板:M5STACK
    [限時福利]5分鐘帶你快速
    一、什么是M5Stack M5Stack是一種模塊化、可堆疊擴展的開發板,每個模塊
    復古留聲機式 arduino 音樂盒
    復古留聲機式 arduino 音
    前言 無論是 arduino 還是 51 還是啥單片機或 STEAM 教育,很多的音樂方面的練習就
    藍牙串口助手 1.3 beta 1測試版
    藍牙串口助手 1.3 beta 1
    在之前版本的基礎上增加了視覺相關功能: 顏色跟蹤模式及人臉跟蹤模式, 增加了發
    【求救】我的M5stickc不知什么原因連不上M5Flow
    【求救】我的M5stickc不知
    密鑰沒填錯有網,就是連不上,大家有沒有試過這種狀況
    Arduino MEGA 與UNO 通過nRF24L模塊通訊
    Arduino MEGA 與UNO 通過n
    之前在深水寶很“實惠”的店鋪買了一些原件,隨手砍了esp8266以及nRF24L*3 因為缺
    Copyright   ©2015-2016  Arduino中文社區  Powered by©Discuz!   
    快速回復 返回頂部 返回列表
    北京快乐8论坛