今回は紙コップとピンポン玉を運び既定の位置に置くロボットをつくり、ロボコンとして競い合った ルールはhttp://yakushi.shinshu-u.ac.jp/robotics/?2017b%2FMission3

ロボット

第一段階

課題をこなすためのロボットとして、二台同時に走らせ効率的に紙コップを回収することにした。 そのため各班に与えられた六つのモータを二つに分け三つで作らなければならない。そこで授業で先生から教えてもらった歯車を使いつかみと持ち上げをモータ一つで賄う方法をためした。

daiitidankaia-mu.jpg

 

daiitidankaia-mu (2).jpg

画像のように歯車を使うことで片方を開閉させ持ち上げることには成功した。しかしながら歯車同士をかみ合わせるための機構(下の画像の左部分)がややこしくかつ重くなってしまったため機体に取り付けたとこ ろ誤差が大きくうまく作動しなかった

第二段階

第一段階でうまくいかなかったので一台にまとめることにした単純にコップをつかむ部分と持ち上げる部分で二つのモータを使うことで機体を簡素化した。

dai2dankaia-mu.jpg

画像のようにつかむ部分をモータにして、モータのついていないほうは紙コップが奥に行き過ぎることを防ぐために突起をつけた

daiitidankaidodai.jpg

車体部分も超音波センサーを縦につけることで誤差を軽減させた。

dainidankai.jpg

しかしながらいざつけてみると画像のようにアームのモータが重く持ち上げたままにすることができなかった。

第三段階

第二段階でアームをつかむ部分にモータをつけると重くなることが分かったので第一段階の歯車を改良した。

daisandankaikitai-5.jpg

画像のように軸に方向を変換できる歯車をつけることで軸が回るとアームが開閉するようにして、アーム同士が合わさり固定されると軸のみが回り上下するようになっている。(画像左がアームをつけた状態・右がアームのない状態)

daisandankaidodai.jpg

車体はキットの説明書に載っているものを改良し、センサを取り付けることで安定した走りにすることができた。画像では超音波センサがないが超音波センサはアームに取り付けていた。

daisandankaikitai-4.jpg

アームと車体をつなげたものアームの先端にゴムの部品をつけることで滑りにくくしている

daisandankaikitai-3.jpg

 

daisanndankaikitai-2.jpg

アームが開いた状態と持ち上がった状態。これでうまくいくかのように思われたがアームと共にセンサも持ち上がったため、紙コップを持ったまま次のコップが探せず、さらにアームと紙コップの接点が二点だったため紙コップが回転した

第四段階

基礎となる部分が第三段階でできたので問題点を改良しそれを二台つくった

daisandannkaikitai.jpg

画像のようにアームのつかむ部分に棒を刺しそこにゴムをつけることで紙コップとの接点を増やし超音波センサをアームの下につけた。

プログラミング

今回プログラミングはチームメイトが行ってくれたので詳しくはhttp://yakushi.shinshu-u.ac.jp/robotics/?2017b%2FMember%2Fibu%2FMission3

概略

2017b-mission3.png

今回は機体を二台に分け赤ラインを一号車、緑ラインを二号車が担当することで効率的にコップを回収しかつどちらかが失敗をしてもある程度ポイントを稼げるようにした

プログラミング

ここではプログラムの概略だけ説明する。今回ライントレース・アームの動作・コップのサーチこの三つを関数化した

import ev3dev.ev3 as ev3
import time

defnite constants, instance, function

mr = ev3.LargeMotor('outC')
assert mr.connected, "Connect right large motor to port C"

ml = ev3.LargeMotor('outA')
assert ml.connected, "Connect left large motor to port A"

arm = ev3.MediumMotor('outB')
assert arm.connected, "Connect arm medium motor to port B"

cs = ev3.ColorSensor()
assert cs.connected, "Connect a color sensor to any sensor port"
cs.mode = 'COL-REFLECT'

us = ev3.UltrasonicSensor()
assert us.connected, "Connect a color sensor to any sensor port"
us.mode = 'US-DIST-CM'


position_sp_to_angle = 1.55
target_val = 50
std_speed = 22
kp = std_speed*0.04
position_sp_to_cm = 20.05
intersection_time = 0.23/1.8
angle_stabilization_time = 0.3*1.8


def run_until_intersection(edge):
    'If it find intersection,it will beep.'
    global global_edge
    global_edge = edge
    start_time = time.time()
    for motor in mr, ml:
        motor.run_direct()
    while time.time()-start_time <= intersection_time:
        line_following(edge)
        if 10 < cs.value() < 100:
            start_time = time.time()
    ev3.Sound.beep()
    while abs(cs.value()-target_val) > 10:
        line_following(edge)
    for motor in mr, ml:
        motor.stop(stop_action='brake')


def line_following(edge):
    'It is used by other function'
    if edge == 'left_edge':
        p = (cs.value()-target_val)*kp
    elif edge == 'right_edge':
        p = (target_val-cs.value())*kp
    else:
        print('invailed edge')
    if p > 0:
        mr.duty_cycle_sp = std_speed-p
        ml.duty_cycle_sp = std_speed
    elif p <= 0:
        mr.duty_cycle_sp = std_speed
        ml.duty_cycle_sp = std_speed+p


def change_following_edge():
    'It is used,when you wanna change following edge'
    line_adjust_by_time(global_edge)
    if global_edge == 'right_edge':
        circle(90)
        move(2)
        circle(-90)
    elif global_edge == 'left_edge':
        circle(-90)
        move(2)
       circle(90)


def move(distance):
    'The argument means cm distance.You can use negative and positive argument'
    for motor in mr, ml:
        motor.run_to_rel_pos(position_sp=distance*position_sp_to_cm,
                             speed_sp=std_speed*5,
                             stop_action='brake')
    for motor in mr, ml:
        motor.wait_while('running')


def circle(rotation_angle):
    'Counterclockwise is positive,like math'
    if rotation_angle < 0:
        signs = [-1, 1]
    elif rotation_angle >= 0:
        signs = [1, -1]
    for motor, sign in zip([mr, ml], signs):
        motor.run_to_rel_pos(position_sp=sign*abs(rotation_angle)*position_sp_to_angle,
                             speed_sp=std_speed*5,
                             stop_action='brake')
    for motor in mr, ml:
        motor.wait_while('running') 


def intersection_go_straight():
    'It is used,when it find a intersection'
    if global_edge == 'left_edge':
        circle(-70*1.2)
    elif global_edge == 'right_edge':
        circle(70*1.2)
    for motor in mr, ml:
        motor.run_direct()
    while abs(cs.value()-target_val) > 10:
        line_following(global_edge)
    for motor in mr, ml:
        motor.stop(stop_action='brake')
 

def intersection_turn_right():
    'It is used,when it find a intersection'
    if global_edge == 'left_edge':
        circle(-145)
        move(2)


def intersection_turn_left():
    'It is used,when it find a intersection'
    if global_edge == 'right_edge':
        circle(145)
        move(2)
 

def init_arm():
    'pos_positive: to inside, pos_negative: to outside'
    arm.reset()  # del stop_action='hold'
    input('Press Enter to initialize closed arm position')
    arm.reset()


def arm_open():
    'You must run init_arm() beforehand'
    arm.run_to_abs_pos(position_sp=200,
                       speed_sp=std_speed*5,
                       stop_action="hold")
    arm.wait_while("running")


def cup_catch():
    'You must run init_arm() beforehand'
    mr.run_forever(speed_sp=std_speed*5)
    ml.run_forever(speed_sp=std_speed*5)
    while us.value() > 50:
        pass
    for motor in mr, ml:
        motor.stop(stop_action='brake')
    move(5)
    arm.run_to_abs_pos(position_sp=0,
                       speed_sp=std_speed*5,
                       stop_action="hold")
    arm.wait_while("running")
    move(-5) 

 
def cup_a_little_lift():
    'You must run init_arm() beforehand'
    arm.run_to_abs_pos(position_sp=-42,
                       speed_sp=std_speed*5,
                       stop_action="hold")
    arm.wait_while("running")


def cup_lift():
    'You must run init_arm() beforehand'
    arm.run_to_abs_pos(position_sp=-230,
                       speed_sp=std_speed*5,
                       stop_action="hold")
    arm.wait_while("running") 


def search_min_d(search_time=4.5, i=1):
    'if i=1 hantokeimawari,i=-1tokeimawari'
    'serch minimum distance and face the angle'
    if i == 1:
        sign = [1, -1]
    elif i == -1:
        sign = [-1, 1]
    min_d = 500
    start_time = time.time()
    mr.run_forever(speed_sp=sign[0]*std_speed*5)
    ml.run_forever(speed_sp=sign[1]*std_speed*5)
    while time.time()-start_time < search_time:
        if min_d > us.value():
            min_d = us.value()
    for motor in mr, ml:
        motor.stop(stop_action='brake')
    start_time = time.time()
    mr.run_forever(speed_sp=sign[1]*std_speed*5)
    ml.run_forever(speed_sp=sign[0]*std_speed*5)
    while time.time()-start_time < search_time:
        if us.value() <= min_d:
            for motor in mr, ml:
                motor.stop(stop_action='brake')
            return
    for motor in mr, ml:
        motor.stop(stop_action='brake')
    search_min_d(search_time)


def line_adjust_by_edge(edge):
    'it is used for avoid misditect as intersection'
    for motor in mr, ml:
        motor.run_direct()
    while abs(cs.value()-target_val) > 10:
        line_following(edge)
    for motor in mr, ml:
        motor.stop(stop_action='brake')


def line_adjust_by_time(edge, stab_time=angle_stabilization_time):
    'it is used for make it parallel to the line'
    for motor in mr, ml:
        motor.run_direct()
    start_time = time.time()
    while time.time()-start_time < stab_time:
        line_following(edge)
    for motor in mr, ml:
        motor.stop(stop_action='brake') 


def run_until_line():
    'finding line,stops.'
    for motor in mr, ml:
        motor.run_forever(speed_sp=std_speed*5)
    while abs(cs.value()-target_val) > 10:
        pass
    for motor in mr, ml:
        motor.stop(stop_action='brake') 

一号車はライントレース、コップをつかむ、xに行く、コップを持ち上げピンポン玉を落とす、yに行き紙コップを置くという動作をするようにした

def arm_set():
    a = input('w, s')
    while a in {'w', 's'}:
        if a == 'w':
            arm.run_timed(time_sp=0.1*1000, speed_sp=200, stop_action='brake')
            arm.wait_while('running')
        elif a == 's':
            arm.run_timed(time_sp=0.1*1000, speed_sp=-200, stop_action='brake')
            arm.wait_while('running')
        a = input('w, s')

'''
def mqtt_send(x): #値を送信
    position = x    #位置情報をアルファベットで送信
    client.publish("position", position)  # "position"というトピックでブローカに送る
    print("send_position_"+x)
'''

def main():
    #client.connect("10.60.2.156",1883, 60) # ブローカに接続、(60秒以上接続がないと切断)
    line_adjust_by_time('left_edge', 1.3)
    run_until_intersection('left_edge')
    intersection_turn_left()
    change_following_edge()
    run_until_intersection('right_edge')
    intersection_turn_right()
    line_adjust_by_time('right_edge', 1)
    run_until_intersection('right_edge')
    circle(145) # intersection,change direction
    arm_open()
    move(-4)
    search_min_d(1)
    cup_catch()
    circle(-105)
    move(1)
    line_adjust_by_time('left_edge', 1)
    circle(-20)
    run_until_intersection('left_edge')
    cup_a_little_lift()
    move(4)
    circle(35)
    move(5)
    cup_a_little_lift()
    move(10)
    cup_lift()
    circle(-30)
    move(-5)
    search_min_d(1, -1)
    cup_catch()
    arm_open()
    cup_a_little_lift()
    circle(60)
    cup_lift()
    circle(-140)
    arm_open()
    move(-4)
    circle(-90)
    #mqtt_send(1)
    move(50)
    #client.disconnect() # 切断


if __name__ == '__main__':
    arm_set()
    init_arm()
    main()

二号車は画像下の紙コップをとる、xに行く、ピンポン玉を落とす、画像上の紙コップをとる、xに行く、ピンポン玉を落とす、yに行く、紙コップを置くという動作をするようにした

rom def_green_v016 import *
def arm_set():
    a = input('w, s')
    while a in {'w', 's'}:
        if a == 'w':
            arm.run_timed(time_sp=0.25*1000, speed_sp=200, stop_action='brake')
            arm.wait_while('running')
        elif a == 's':
            arm.run_timed(time_sp=0.25*1000, speed_sp=-200, stop_action='brake')
            arm.wait_while('running')
        a = input('w, s')


def main() 

    run_until_line()
    move(4)
    line_adjust_by_edge('right_edge')
    run_until_intersection('right_edge')
    circle(33)
    arm_open()
    search_min_d(0.8)
    cup_catch()
    circle(-160)
    line_adjust_by_edge('left_edge')
    run_until_intersection('left_edge')
    intersection_turn_left()
    line_adjust_by_time('left_edge', 1.3)
    cup_a_little_lift()
    move(5)
    cup_lift()
    move(-50)
    line_adjust_by_time('left_edge', 5)
    run_until_intersection('left_edge')
    move(15)
    circle(35*1.2)
    line_adjust_by_edge('left_edge')
    line_adjust_by_time('left_edge', 3)
    run_until_intersection('left_edge')
    intersection_turn_left()
    run_until_intersection('left_edge')
    circle(-27)
    arm_open()
    
if __name__ == '__main__':
    arm_set()
    init_arm()
    main()

結果

今回自分たちのチームは基本点8技術点10.7で総合2位だった。しかしながらうまくいかなかった部分が多々あり悔しい結果であった。改善点としてはセンサでの誤差をアームでカバーするために可動域を広くするというのが見つかった。これで最後の課題となったがまだまだ自分たちは未熟であるためこれからもしっかりと学んでいきたい


添付ファイル: file2017b-mission3.png 207件 [詳細] filekekka.jpg 100件 [詳細] filedaisanndankaikitai-2.jpg 202件 [詳細] filedaisandannkaikitai.jpg 236件 [詳細] filedaisandankaikitai-5.jpg 236件 [詳細] filedaisandankaikitai-4.jpg 254件 [詳細] filedaisandankaikitai-3.jpg 191件 [詳細] filedaisandankaidodai.jpg 242件 [詳細] filedainidankai-2.jpg 118件 [詳細] filedainidankai.jpg 239件 [詳細] filedaiitidankaidodai.jpg 214件 [詳細] filedaiitidankaia-mu.jpg 254件 [詳細] filedaiitidankaia-mu (2).jpg 222件 [詳細] filedai2dankaia-mu.jpg 235件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-02-11 (日) 10:53:50