티스토리 뷰

모바일 로봇의 알고리즘을 검증하고 싶은경우, 특히 멀티로봇시스템에 대한 알고리즘을 테스트해보고 싶을 경우 할일이 너무 많다. 가장 간단한 플랫폼 중 하나인 터틀봇을 사용한다고 쳐도 가격이 만만치 않고 어찌어찌 몇대 구했다고 하더라도 일일이 세팅에 통신망 구축에, 귀찮은 일이 너무 많다.

대신 실험해주는 사람이 있다면 정말 편할 텐데라는 생각을 항상하는데, 무려 이것을 대신 해주는 플랫폼이 존재한다. (그것도 무료로)

 Robotarium

사이트 주소: https://www.robotarium.gatech.edu/

조지아 텍(Georgia Tech)에서는 모바일 로봇 알고리즘을 무료로 시험해볼 수 있는 온라인 플랫폼을 제공한다. 여러대의 로봇을 미리 준비해두고 알고리즘 개발자가 코드를 전송하면 이를 원격으로 실행해주고 결과를 영상으로 보내준다. 간단한 소개 영상은 아래와 같다.

사용법은 사이트에 들어가면 Document들에서 친절하게 설명해준다.

실험을 돌리기전에 미리 테스트 해볼 시뮬레이터(MATLAB, Python)도 제공하기 때문에 미리 유효성에 대한 테스트를 해보는 것을 추천

예제

예제는 저번 포스트에서 소개한 헝가리안 알고리즘을 적용해서 로봇들이 임무를 완수할 때 마다 새로운 임무를 할당시켜주는 간단한 시나리오 에대한 테스트를 진행해봤다.

파이썬 시뮬레이터 예시

먼저 위와 같이 시뮬레이팅을 진행하고, 코드를 robotarium에 전송해 테스트 해달라고 부탁을하면

 

robotarium 실험 영상

대략 45초까지가 initializing 단계이고 그 이후부터가 본격적인 시뮬레이션 영상

 

이렇게 자동으로 테스트를 해서 보여준다. 아무래도 지금 진행하는 임무 계획연구가 기존 경영 과학이나 경제학 분야에서와 조금 다른 점은 로봇의 실제 운용을 고려해야하는데, 아직은 고려하고 있지 않기 때문에 이런 테스트 베드를 활용한다면 로봇의 모션이나 패스를 고려해서 더 현실적으로 로봇에 응용할 만한 임무 계획 알고리즘을 만들고 실험할 수 있지 않을까 기대해본다.

코드

import rps.robotarium as robotarium
from rps.utilities.transformations import *
from rps.utilities.barrier_certificates import *
from rps.utilities.misc import *
from rps.utilities.controllers import *

import numpy as np
from scipy.spatial import distance_matrix
from scipy.optimize import linear_sum_assignment


# Initial condition of experiment
np.random.seed(1)

n_robot = 4
n_task = 4

lower_x = -1.5
lower_y = -0.9

width = 3
height = 1.8

# Randomly generates the pose of robots
robot_pos = np.zeros((n_robot,3))
task_pos = np.zeros((n_task,3))

robot_pos[:,0] = np.random.uniform(lower_x,lower_x+width,size=n_robot)
robot_pos[:,1] = np.random.uniform(lower_y,lower_y+height,size=n_robot)

r = robotarium.Robotarium(number_of_robots=n_robot,
                              show_figure=True,
                              initial_conditions=robot_pos.T,
                              sim_in_real_time=True)

# Create single integrator position controller
single_integrator_position_controller = create_si_position_controller()

# Create barrier certificates to avoid collision
si_barrier_cert = create_single_integrator_barrier_certificate_with_boundary()

_, uni_to_si_states = create_si_to_uni_mapping()

# Create mapping from single integrator velocity commands to unicycle velocity commands
si_to_uni_dyn = create_si_to_uni_dynamics_with_backwards_motion()

# Plotting Parameters
CM = np.random.rand(n_robot,3) # Random Colors
task_marker_size_m = 0.2
robot_marker_size_m = 0.15
marker_size_task = determine_marker_size(r,task_marker_size_m)
marker_size_robot = determine_marker_size(r, robot_marker_size_m)
font_size = determine_font_size(r,0.1)
line_width = 3

for i in range(5):
    # Initialize requested tasks
    task_pos[:,0] = np.random.uniform(lower_x,lower_x+width,size=n_task)
    task_pos[:,1] = np.random.uniform(lower_y,lower_y+height,size=n_task)
    
    x = r.get_poses()
    x_si = uni_to_si_states(x)

    # Calculates a distance matrix as the cost
    cost = distance_matrix(x.T[:,:2], task_pos[:,:2])
    # Hungarian algorithm
    row_ind, col_ind = linear_sum_assignment(cost)
    # Cacluates the total cost of the result
    total_cost = cost[row_ind, col_ind].sum()
    # Get goal position from assignment    
    goal_pos = task_pos[col_ind,:]

    # Text with goal identification
    task_caption = ['T{0}'.format(ii) for ii in range(task_pos.T.shape[1])]
    #Plot text for caption
    task_points_text = [r.axes.text(goal_pos.T[0,ii], goal_pos.T[1,ii], task_caption[ii], fontsize=font_size, color='k',fontweight='bold',horizontalalignment='center',verticalalignment='center',zorder=-2)
    for ii in range(task_pos.T.shape[1])]
    # Plot task markers
    task_markers = [r.axes.scatter(goal_pos.T[0,ii], goal_pos.T[1,ii], s=marker_size_task, marker='s', facecolors='none',edgecolors=CM[ii,:],linewidth=line_width,zorder=-2)
    for ii in range(task_pos.T.shape[1])]
    # Plot robot positions
    robot_markers = [r.axes.scatter(x[0,ii], x[1,ii], s=marker_size_robot, marker='o', facecolors='none',edgecolors=CM[ii,:],linewidth=line_width) 
    for ii in range(task_pos.T.shape[1])]

    r.step()

    while(np.size(at_pose(np.vstack((x_si,x[2,:])), goal_pos.T, rotation_error=100)) != n_robot):
        
        # Get poses of agents
        x = r.get_poses()
        x_si = uni_to_si_states(x)
        
        # Update Plot
        # Update Robot Marker Plotted Visualization
        for i in range(x.shape[1]):
            robot_markers[i].set_offsets(x[:2,i].T)
        
        # Create single-integrator control inputs
        dxi = single_integrator_position_controller(x_si, goal_pos.T[:2][:])
        
        # Create safe control inputs (i.e., no collisions)
        dxi = si_barrier_cert(dxi, x_si)
        
        # Transform single integrator velocity commands to unicycle
        dxu = si_to_uni_dyn(dxi, x)
        
        # Set the velocities by mapping the single-integrator inputs to unciycle inputs
        r.set_velocities(np.arange(n_robot), dxu)
        # Iterate the simulation
        r.step()
    
    # Remove previous plots
    for i in range(n_task):
        task_points_text[i].remove()
        task_markers[i].remove()
        
    for i in range(n_robot):
        robot_markers[i].remove()
        
#Call at end of script to print debug information and for your script to run on the Robotarium server properly
r.call_at_scripts_end()

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31