from __future__ import print_function
import pygame
import sys, os, getopt, math, random
import numpy as np
import pickle
swarm_size = 30
manual_mode = False
try:
opts, args = getopt.getopt(sys.argv[1:], 'n:', ['manual'])
except getopt.GetoptError as err:
print(str(err))
sys.exit()
for opt,arg in opts:
if opt == '-n':
swarm_size = int(arg)
elif opt == '--manual':
manual_mode = True
power_exponent = 1.3
pixels_per_length = 50
def cal_world_side_coef():
desired_screen_size = 400
desired_world_size = float(desired_screen_size) / pixels_per_length
return desired_world_size / pow(30, 1/power_exponent)
world_side_coef = cal_world_side_coef()
world_side_length = world_side_coef * pow(swarm_size, 1/power_exponent)
world_size = (world_side_length, world_side_length)
screen_side_length = int(pixels_per_length * world_side_length)
screen_size = (screen_side_length, screen_side_length)
comm_range = 0.65
desired_space_ratio = 0.8
desired_space = comm_range * desired_space_ratio
perp_thres = math.pi/18
devia_angle = math.pi/9
loop_folder = "loop-data2"
shape_catalog = ["airplane", "circle", "cross", "goblet", "hand", "K", "lamp", "square",
"star", "triangle", "wrench"]
shape_quantity = len(shape_catalog)
shape_decision = -1
assignment_scheme = np.zeros(swarm_size)
force_shape_set = range(shape_quantity)
robot_poses = np.random.rand(swarm_size, 2) * world_side_length
dist_table = np.zeros((swarm_size, swarm_size))
conn_table = np.zeros((swarm_size, swarm_size))
conn_lists = [[] for i in range(swarm_size)]
def dist_conn_update():
global dist_table
global conn_table
global conn_lists
conn_lists = [[] for i in range(swarm_size)]
for i in range(swarm_size):
for j in range(i+1, swarm_size):
dist_temp = np.linalg.norm(robot_poses[i] - robot_poses[j])
dist_table[i,j] = dist_temp
dist_table[j,i] = dist_temp
if dist_temp > comm_range:
conn_table[i,j] = 0
conn_table[j,i] = 0
else:
conn_table[i,j] = 1
conn_table[j,i] = 1
conn_lists[i].append(j)
conn_lists[j].append(i)
dist_conn_update()
disp_poses = []
def disp_poses_update():
global disp_poses
poses_temp = robot_poses / world_side_length
poses_temp[:,1] = 1.0 - poses_temp[:,1]
poses_temp = poses_temp * screen_side_length
disp_poses = poses_temp.astype(int)
disp_poses_update()
seed_percentage = 0.1
seed_quantity = min(max(int(swarm_size*seed_percentage), 1), swarm_size)
robot_seeds = [False for i in range(swarm_size)]
seed_list_temp = np.arange(swarm_size)
np.random.shuffle(seed_list_temp)
for i in seed_list_temp[:seed_quantity]:
robot_seeds[i] = True
color_white = (255,255,255)
color_black = (0,0,0)
color_grey = (128,128,128)
color_red = (255,0,0)
distinct_color_set = ((230,25,75), (60,180,75), (255,225,25), (0,130,200), (245,130,48),
(145,30,180), (70,240,240), (240,50,230), (210,245,60), (250,190,190),
(0,128,128), (230,190,255), (170,110,40), (128,0,0),
(170,255,195), (128,128,0), (0,0,128))
color_quantity = 17
robot_size_formation = 5
robot_width_empty = 2
conn_width_formation = 2
robot_size_consensus = 7
conn_width_thin_consensus = 2
conn_width_thick_consensus = 4
robot_ring_size = 9
pygame.init()
font = pygame.font.SysFont("Cabin", 12)
icon = pygame.image.load("icon_geometry_art.jpg")
pygame.display.set_icon(icon)
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption("Demo 1")
screen.fill(color_white)
for i in range(swarm_size):
pygame.draw.circle(screen, color_black, disp_poses[i], robot_size_formation,
robot_width_empty)
pygame.display.update()
raw_input("<Press Enter to continue>")
def S14_robot_grouping(robot_list, robot_group_ids, groups):
groups_temp = {}
for i in robot_list:
group_id_temp = robot_group_ids[i]
if group_id_temp not in groups_temp.keys():
groups_temp[group_id_temp] = [i]
else:
groups_temp[group_id_temp].append(i)
group_id_max = -1
if len(groups_temp.keys()) > 1:
group_id_max = groups_temp.keys()[0]
size_max = len(groups[group_id_max][0])
for group_id_temp in groups_temp.keys()[1:]:
size_temp = len(groups[group_id_temp][0])
if size_temp > size_max:
group_id_max = group_id_temp
size_max = size_temp
else:
group_id_max = groups_temp.keys()[0]
return groups_temp, group_id_max
def S14_closest_robot(robot_host, robot_neighbors):
robot_closest = robot_neighbors[0]
dist_closest = dist_table[robot_host,robot_closest]
for i in robot_neighbors[1:]:
dist_temp = dist_table[robot_host,i]
if dist_temp < dist_closest:
robot_closest = i
dist_closest = dist_temp
return robot_closest
def normalize(v):
norm = np.linalg.norm(v)
if norm == 0:
return v
return v/norm
def reset_radian(radian):
while radian >= math.pi:
radian = radian - 2*math.pi
while radian < -math.pi:
radian = radian + 2*math.pi
return radian
def robot_boundary_check(robot_pos, robot_ori):
new_ori = robot_ori
if robot_pos[0] >= world_side_length:
if math.cos(new_ori) > 0:
new_ori = reset_radian(2*(math.pi/2) - new_ori)
if new_ori > 0:
if (math.pi - new_ori) < perp_thres:
new_ori = new_ori - devia_angle
else:
if (new_ori + math.pi) < perp_thres:
new_ori = new_ori + devia_angle
elif robot_pos[0] <= 0:
if math.cos(new_ori) < 0:
new_ori = reset_radian(2*(math.pi/2) - new_ori)
if new_ori > 0:
if new_ori < perp_thres:
new_ori = new_ori + devia_angle
else:
if (-new_ori) < perp_thres:
new_ori = new_ori - devia_angle
if robot_pos[1] >= world_side_length:
if math.sin(new_ori) > 0:
new_ori = reset_radian(2*(0) - new_ori)
if new_ori > -math.pi/2:
if (new_ori + math.pi/2) < perp_thres:
new_ori = new_ori + devia_angle
else:
if (-math.pi/2 - new_ori) < perp_thres:
new_ori = new_ori - devia_angle
elif robot_pos[1] <= 0:
if math.sin(new_ori) < 0:
new_ori = reset_radian(2*(0) - new_ori)
if new_ori > math.pi/2:
if (new_ori - math.pi/2) < perp_thres:
new_ori = new_ori + devia_angle
else:
if (math.pi/2 - new_ori) < perp_thres:
new_ori = new_ori - devia_angle
return new_ori
while True:
print("##### simulation 1: network aggregation #####")
robot_states = np.array([-1 for i in range(swarm_size)])
n1_life_lower = 2
n1_life_upper = 6
robot_n1_lives = np.random.uniform(n1_life_lower, n1_life_upper, swarm_size)
robot_oris = np.random.rand(swarm_size) * 2 * math.pi - math.pi
groups = {}
life_incre = 5
group_id_upper = swarm_size
robot_group_ids = np.array([-1 for i in range(swarm_size)])
step_moving_dist = 0.05
destination_error = 0.08
mov_vec_ratio = 0.5
sim_haulted = False
time_last = pygame.time.get_ticks()
time_now = time_last
frame_period = 50
sim_freq_control = True
iter_count = 0
print("swarm robots are aggregating to one network ...")
swarm_aggregated = False
ending_period = 3.0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("program exit in simulation 1")
sys.exit()
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
sim_haulted = not sim_haulted
if sim_haulted: continue
if sim_freq_control:
time_now = pygame.time.get_ticks()
if (time_now - time_last) > frame_period:
time_last = time_now
else:
continue
iter_count = iter_count + 1
st_n1to0 = []
st_gton1 = []
st_0to1_join = {}
st_0to1_new = {}
dist_conn_update()
for i in range(swarm_size):
if robot_states[i] == -1:
if robot_n1_lives[i] < 0:
st_n1to0.append(i)
else:
conn_temp = conn_lists[i][:]
for j in conn_lists[i]:
if robot_states[j] != 1:
conn_temp.remove(j)
if len(conn_temp) != 0:
groups_local, group_id_max = S14_robot_grouping(conn_temp,
robot_group_ids, groups)
for group_id_temp in groups_local.keys():
if (group_id_temp != group_id_max) and (group_id_temp not in st_gton1):
st_gton1.append(group_id_temp)
robot_closest = S14_closest_robot(i, groups_local[group_id_max])
vect_temp = robot_poses[i] - robot_poses[robot_closest]
robot_oris[i] = math.atan2(vect_temp[1], vect_temp[0])
elif robot_states[i] == 0:
state1_list = []
state0_list = []
for j in conn_lists[i]:
if robot_states[j] == 1:
state1_list.append(j)
elif robot_states[j] == 0:
state0_list.append(j)
if len(state1_list) != 0:
groups_local, group_id_max = S14_robot_grouping(state1_list,
robot_group_ids, groups)
for group_id_temp in groups_local.keys():
if (group_id_temp != group_id_max) and (group_id_temp not in st_gton1):
st_gton1.append(group_id_temp)
st_0to1_join[i] = group_id_max
elif len(state0_list) != 0:
st_0to1_new[i] = S14_closest_robot(i, state0_list)
elif robot_states[i] == 1:
conn_temp = conn_lists[i][:]
has_other_group = False
host_group_id = robot_group_ids[i]
for j in conn_lists[i]:
if robot_states[j] != 1:
conn_temp.remove(j)
else:
if robot_group_ids[j] != host_group_id:
has_other_group = True
if has_other_group:
groups_local, group_id_max = S14_robot_grouping(conn_temp,
robot_group_ids, groups)
for group_id_temp in groups_local.keys():
if (group_id_temp != group_id_max) and (group_id_temp not in st_gton1):
st_gton1.append(group_id_temp)
else:
print("robot state error")
sys.exit()
for group_id_temp in groups.keys():
if groups[group_id_temp][1] < 0:
if group_id_temp not in st_gton1:
st_gton1.append(group_id_temp)
for robot_temp in st_0to1_join.keys():
group_id_temp = st_0to1_join[robot_temp]
robot_states[robot_temp] = 1
robot_group_ids[robot_temp] = group_id_temp
groups[group_id_temp][0].append(robot_temp)
groups[group_id_temp][1] = groups[group_id_temp][1] + life_incre
for group_id_temp in st_gton1:
for robot_temp in groups[group_id_temp][0]:
robot_states[robot_temp] = -1
robot_n1_lives[robot_temp] = np.random.uniform(n1_life_lower, n1_life_upper)
robot_group_ids[robot_temp] = -1
robot_oris[robot_temp] = np.random.rand() * 2 * math.pi - math.pi
groups.pop(group_id_temp)
while len(st_0to1_new.keys()) != 0:
pair0 = st_0to1_new.keys()[0]
pair1 = st_0to1_new[pair0]
st_0to1_new.pop(pair0)
if (pair1 in st_0to1_new.keys()) and (st_0to1_new[pair1] == pair0):
st_0to1_new.pop(pair1)
if robot_seeds[pair0] or robot_seeds[pair1]:
group_id_temp = np.random.randint(0, group_id_upper)
while group_id_temp in groups.keys():
group_id_temp = np.random.randint(0, group_id_upper)
robot_states[pair0] = 1
robot_states[pair1] = 1
robot_group_ids[pair0] = group_id_temp
robot_group_ids[pair1] = group_id_temp
groups[group_id_temp] = [[pair0, pair1], life_incre*2, False]
for robot_temp in st_n1to0:
robot_states[robot_temp] = 0
for group_id_temp in groups.keys():
if len(groups[group_id_temp][0]) > swarm_size/2.0:
groups[group_id_temp][2] = True
else:
groups[group_id_temp][2] = False
local_conn_lists = [[] for i in range(swarm_size)]
robot_poses_t = np.copy(robot_poses)
for i in range(swarm_size):
if robot_states[i] == 1:
host_group_id = robot_group_ids[i]
for j in conn_lists[i]:
if (robot_states[j] == 1) and (robot_group_ids[j] == host_group_id):
local_conn_lists[i].append(j)
if len(local_conn_lists[i]) == 0:
printf("robot {} loses its group {}".format(i, host_group_id))
sys.exit()
if (len(local_conn_lists[i]) == 1) and (len(groups[host_group_id][0]) > 2):
center = local_conn_lists[i][0]
if dist_table[i,center] > (desired_space + step_moving_dist):
robot_oris[i] = math.atan2(robot_poses_t[center,1] - robot_poses_t[i,1],
robot_poses_t[center,0] - robot_poses_t[i,0])
elif (dist_table[i,center] + step_moving_dist) < desired_space:
robot_oris[i] = math.atan2(robot_poses_t[i,1] - robot_poses_t[center,1],
robot_poses_t[i,0] - robot_poses_t[center,0])
else:
robot_oris[i] = math.atan2(robot_poses_t[i,1] - robot_poses_t[center,1],
robot_poses_t[i,0] - robot_poses_t[center,0])
int_angle_temp = math.acos((math.pow(dist_table[i,center],2) +
math.pow(step_moving_dist,2) - math.pow(desired_space,2)) /
(2.0*dist_table[i,center]*step_moving_dist))
robot_oris[i] = reset_radian(robot_oris[i] + (math.pi - int_angle_temp))
else:
mov_vec = np.zeros(2)
for j in local_conn_lists[i]:
mov_vec = mov_vec + (mov_vec_ratio * (dist_table[i,j] - desired_space) *
normalize(robot_poses_t[j] - robot_poses_t[i]))
if np.linalg.norm(mov_vec) < destination_error:
continue
else:
robot_oris[i] = math.atan2(mov_vec[1], mov_vec[0])
robot_oris[i] = robot_boundary_check(robot_poses_t[i], robot_oris[i])
robot_poses[i] = robot_poses_t[i] + (step_moving_dist *
np.array([math.cos(robot_oris[i]), math.sin(robot_oris[i])]))
disp_poses_update()
screen.fill(color_white)
for i in range(swarm_size):
if robot_seeds[i]:
color_temp = color_red
else:
color_temp = color_grey
if robot_states[i] == -1:
pygame.draw.circle(screen, color_temp, disp_poses[i],
robot_size_formation, robot_width_empty)
elif robot_states[i] == 0:
pygame.draw.circle(screen, color_temp, disp_poses[i],
robot_size_formation, 0)
for group_id_temp in groups.keys():
if groups[group_id_temp][2]:
color_group = color_black
else:
color_group = color_grey
conn_draw_sets = []
for i in groups[group_id_temp][0]:
for j in local_conn_lists[i]:
if set([i,j]) not in conn_draw_sets:
pygame.draw.line(screen, color_group, disp_poses[i],
disp_poses[j], conn_width_formation)
conn_draw_sets.append(set([i,j]))
if robot_seeds[i]:
pygame.draw.circle(screen, color_red, disp_poses[i],
robot_size_formation, 0)
else:
pygame.draw.circle(screen, color_group, disp_poses[i],
robot_size_formation, 0)
pygame.display.update()
for i in range(swarm_size):
if robot_states[i] == -1:
robot_n1_lives[i] = robot_n1_lives[i] - frame_period/1000.0
for group_id_temp in groups.keys():
if not groups[group_id_temp][2]:
groups[group_id_temp][1] = groups[group_id_temp][1] - frame_period/1000.0
if not swarm_aggregated:
if (len(groups.keys()) == 1) and (len(groups.values()[0][0]) == swarm_size):
swarm_aggregated = True
if swarm_aggregated:
if ending_period <= 0:
print("simulation 1 is finished")
if manual_mode: raw_input("<Press Enter to continue>")
print("")
break
else:
ending_period = ending_period - frame_period/1000.0
print("##### simulation 2: decision making #####")
dist_conn_update()
disp_poses_update()
screen.fill(color_white)
for i in range(swarm_size):
pygame.draw.circle(screen, color_black, disp_poses[i], robot_size_consensus, 0)
for j in range(i+1, swarm_size):
if conn_table[i,j]:
pygame.draw.line(screen, color_black, disp_poses[i], disp_poses[j],
conn_width_thin_consensus)
pygame.display.update()
shape_decision = -1
deci_dist = np.random.rand(swarm_size, shape_quantity)
sum_temp = np.sum(deci_dist, axis=1)
for i in range(swarm_size):
deci_dist[i] = deci_dist[i] / sum_temp[i]
deci_domi = np.argmax(deci_dist, axis=1)
groups = []
robot_group_sizes = [0 for i in range(swarm_size)]
color_initialized = False
deci_colors = [-1 for i in range(shape_quantity)]
color_assigns = [0 for i in range(color_quantity)]
group_colors = []
robot_colors = [0 for i in range(swarm_size)]
dist_diff_thres = 0.3
dist_diff_ratio = [0.0 for i in range(swarm_size)]
dist_diff_power = 0.3
sim_haulted = False
time_last = pygame.time.get_ticks()
time_now = time_last
frame_period = 1000
sim_freq_control = True
iter_count = 0
sys.stdout.write("iteration {}".format(iter_count))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("program exit in simulation 2")
sys.exit()
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
sim_haulted = not sim_haulted
if sim_haulted: continue
if sim_freq_control:
time_now = pygame.time.get_ticks()
if (time_now - time_last) > frame_period:
time_last = time_now
else:
continue
iter_count = iter_count + 1
sys.stdout.write("\riteration {}".format(iter_count))
sys.stdout.flush()
deci_domi = np.argmax(deci_dist, axis=1)
groups = []
group_deci = []
robot_pool = range(swarm_size)
while len(robot_pool) != 0:
first_member = robot_pool[0]
group_temp = [first_member]
robot_pool.pop(0)
p_members = list(conn_lists[first_member])
p_index = 0
current_domi = deci_domi[first_member]
while p_index < len(p_members):
if deci_domi[p_members[p_index]] == current_domi:
new_member = p_members[p_index]
p_members.remove(new_member)
robot_pool.remove(new_member)
group_temp.append(new_member)
p_members_new = conn_lists[new_member]
for member in p_members_new:
if member not in p_members:
if member not in group_temp:
if member in robot_pool:
p_members.append(member)
else:
p_index = p_index + 1
groups.append(group_temp)
group_deci.append(deci_domi[first_member])
if not color_initialized:
color_initialized = True
select_set = range(color_quantity)
all_deci_set = set(group_deci)
for deci in all_deci_set:
if len(select_set) == 0:
select_set = range(color_quantity)
chosen_color = np.random.choice(select_set)
select_set.remove(chosen_color)
deci_colors[deci] = chosen_color
color_assigns[chosen_color] = color_assigns[chosen_color] + 1
else:
all_deci_set = set(group_deci)
for i in range(shape_quantity):
if deci_colors[i] != -1:
if i not in all_deci_set:
color_assigns[deci_colors[i]] = color_assigns[deci_colors[i]] - 1
deci_colors[i] = -1
select_set = []
for i in range(len(groups)):
if deci_colors[group_deci[i]] == -1:
if len(select_set) == 0:
color_assigns_min = min(color_assigns)
color_assigns_temp = [j - color_assigns_min for j in color_assigns]
select_set = range(color_quantity)
for j in range(color_quantity):
if color_assigns_temp[j] != 0:
select_set.remove(j)
chosen_color = np.random.choice(select_set)
select_set.remove(chosen_color)
deci_colors[group_deci[i]] = chosen_color
color_assigns[chosen_color] = color_assigns[chosen_color] + 1
group_colors = []
for i in range(len(groups)):
group_colors.append(deci_colors[group_deci[i]])
for i in range(len(groups)):
size_temp = len(groups[i])
color_temp = group_colors[i]
for robot in groups[i]:
robot_group_sizes[robot] = size_temp
robot_colors[robot] = color_temp
converged_all = True
deci_dist_t = np.copy(deci_dist)
for i in range(swarm_size):
host_domi = deci_domi[i]
converged = True
for neighbor in conn_lists[i]:
if host_domi != deci_domi[neighbor]:
converged = False
break
if converged:
deci_dist[i] = deci_dist_t[i]*1.0
for neighbor in conn_lists[i]:
deci_dist[i] = deci_dist[i] + deci_dist_t[neighbor]
sum_temp = np.sum(deci_dist[i])
deci_dist[i] = deci_dist[i] / sum_temp
comb_pool = [i] + list(conn_lists[i])
comb_pool_len = len(comb_pool)
dist_diff = []
for j in range(comb_pool_len):
for k in range(j+1, comb_pool_len):
j_robot = comb_pool[j]
k_robot = comb_pool[k]
dist_diff.append(np.sum(abs(deci_dist[j_robot] - deci_dist[k_robot])))
dist_diff_max = max(dist_diff)
if dist_diff_max < dist_diff_thres:
dist_diff_ratio = dist_diff_max/dist_diff_thres
small_end = 1.0/shape_quantity * np.power(dist_diff_ratio, dist_diff_power)
large_end = 2.0/shape_quantity - small_end
dist_temp = np.copy(deci_dist[i])
sort_index = range(shape_quantity)
for j in range(shape_quantity-1):
for k in range(shape_quantity-1-j):
if dist_temp[k] > dist_temp[k+1]:
temp = dist_temp[k]
dist_temp[k] = dist_temp[k+1]
dist_temp[k+1] = temp
temp = sort_index[k]
sort_index[k] = sort_index[k+1]
sort_index[k+1] = temp
for j in range(shape_quantity):
multiplier = small_end + float(j)/(shape_quantity-1) * (large_end-small_end)
deci_dist[i][sort_index[j]] = deci_dist[i][sort_index[j]] * multiplier
sum_temp = np.sum(deci_dist[i])
deci_dist[i] = deci_dist[i]/sum_temp
else:
pass
else:
converged_all = False
deci_dist[i] = deci_dist_t[i]*robot_group_sizes[i]
for neighbor in conn_lists[i]:
deci_dist[i] = deci_dist[i] + deci_dist_t[neighbor]*robot_group_sizes[neighbor]
sum_temp = np.sum(deci_dist[i])
deci_dist[i] = deci_dist[i] / sum_temp
screen.fill(color_white)
for i in range(swarm_size):
for j in range(i+1, swarm_size):
if conn_table[i,j]:
pygame.draw.line(screen, color_black, disp_poses[i], disp_poses[j],
conn_width_thin_consensus)
for i in range(len(groups)):
group_len = len(groups[i])
for j in range(group_len):
for k in range(j+1, group_len):
j_robot = groups[i][j]
k_robot = groups[i][k]
if conn_table[j_robot,k_robot]:
pygame.draw.line(screen, distinct_color_set[group_colors[i]],
disp_poses[j_robot], disp_poses[k_robot], conn_width_thick_consensus)
for i in range(swarm_size):
pygame.draw.circle(screen, distinct_color_set[robot_colors[i]],
disp_poses[i], robot_size_consensus, 0)
pygame.display.update()
if converged_all:
shape_decision = deci_domi[0]
print("")
print("converged to decision {}: {}".format(shape_decision,
shape_catalog[shape_decision]))
print("simulation 2 is finished")
if manual_mode: raw_input("<Press Enter to continue>")
print("")
break
print("##### simulation 3: role assignment #####")
dist_conn_update()
disp_poses_update()
screen.fill(color_white)
for i in range(swarm_size):
pygame.draw.circle(screen, color_black, disp_poses[i], robot_size_consensus, 0)
for j in range(i+1, swarm_size):
if conn_table[i,j]:
pygame.draw.line(screen, color_black, disp_poses[i], disp_poses[j],
conn_width_thin_consensus)
pygame.display.update()
gradients = np.copy(conn_table)
pool_gradient = 1
pool_conn = {}
for i in range(swarm_size):
pool_conn[i] = conn_lists[i][:]
while len(pool_conn.keys()) != 0:
source_deactivate = []
for source in pool_conn:
targets_temp = []
for target in pool_conn[source]:
for target_new in conn_lists[target]:
if target_new == source: continue
if gradients[source, target_new] == 0:
gradients[source, target_new] = pool_gradient + 1
targets_temp.append(target_new)
if len(targets_temp) == 0:
source_deactivate.append(source)
else:
pool_conn[source] = targets_temp[:]
for source in source_deactivate:
pool_conn.pop(source)
pool_gradient = pool_gradient + 1
gradients_rel = []
for i in range(swarm_size):
gradient_temp = np.zeros((swarm_size, swarm_size))
for j in range(swarm_size):
gradient_temp[j] = gradients[i] - gradients[i,j]
gradients_rel.append(gradient_temp)
neighbors_send = [[[] for j in range(swarm_size)] for i in range(swarm_size)]
for i in range(swarm_size):
for j in range(swarm_size):
for neighbor in conn_lists[j]:
if gradients_rel[i][j,neighbor] == 1:
neighbors_send[i][j].append(neighbor)
pref_dist = np.random.rand(swarm_size, swarm_size)
initial_roles = np.argmax(pref_dist, axis=1)
local_role_assignment = [[[-1, 0, -1] for j in range(swarm_size)] for i in range(swarm_size)]
local_robot_assignment = [[[] for j in range(swarm_size)] for i in range(swarm_size)]
for i in range(swarm_size):
local_role_assignment[i][i][0] = initial_roles[i]
local_role_assignment[i][i][1] = pref_dist[i, initial_roles[i]]
local_role_assignment[i][i][2] = 0
local_robot_assignment[i][initial_roles[i]].append(i)
message_rx = [[] for i in range(swarm_size)]
transmission_total = 0
iter_count = 0
for source in range(swarm_size):
chosen_role = local_role_assignment[source][source][0]
message_temp = [source, chosen_role, pref_dist[source, chosen_role], iter_count]
for target in conn_lists[source]:
message_rx[target].append(message_temp)
transmission_total = transmission_total + 1
role_color = [0 for i in range(swarm_size)]
role_index_pool = range(swarm_size)
random.shuffle(role_index_pool)
color_index_pool = range(color_quantity)
random.shuffle(color_index_pool)
while len(role_index_pool) != 0:
role_color[role_index_pool[0]] = color_index_pool[0]
role_index_pool.pop(0)
color_index_pool.pop(0)
if len(color_index_pool) == 0:
color_index_pool = range(color_quantity)
random.shuffle(color_index_pool)
transmit_flag = [[False for j in range(swarm_size)] for i in range(swarm_size)]
change_flag = [False for i in range(swarm_size)]
scheme_converged = [False for i in range(swarm_size)]
sim_haulted = False
time_last = pygame.time.get_ticks()
time_now = time_last
time_period = 2000
sim_freq_control = True
flash_delay = 200
sys.stdout.write("iteration {}".format(iter_count))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("program exit in simulation 3")
sys.exit()
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
sim_haulted = not sim_haulted
if sim_haulted: continue
if sim_freq_control:
time_now = pygame.time.get_ticks()
if (time_now - time_last) > time_period:
time_last = time_now
else:
continue
iter_count = iter_count + 1
sys.stdout.write("\riteration {}".format(iter_count))
sys.stdout.flush()
message_rx_buf = [[[k for k in j] for j in i] for i in message_rx]
message_rx = [[] for i in range(swarm_size)]
yield_robots = []
yield_roles = []
for i in range(swarm_size):
for message in message_rx_buf[i]:
source = message[0]
role = message[1]
probability = message[2]
time_stamp = message[3]
if source == i:
print("error, robot {} receives message of itself".format(i))
sys.exit()
if time_stamp > local_role_assignment[i][source][2]:
role_old = local_role_assignment[i][source][0]
if role_old >= 0:
local_robot_assignment[i][role_old].remove(source)
local_robot_assignment[i][role].append(source)
local_role_assignment[i][source][0] = role
local_role_assignment[i][source][1] = probability
local_role_assignment[i][source][2] = time_stamp
transmit_flag[i][source] = True
if role == local_role_assignment[i][i][0]:
if probability >= pref_dist[i, local_role_assignment[i][i][0]]:
change_flag[i] = True
yield_robots.append(i)
yield_roles.append(local_role_assignment[i][i][0])
for i in range(swarm_size):
if change_flag[i]:
change_flag[i] = False
role_old = local_role_assignment[i][i][0]
pref_dist_temp = np.copy(pref_dist[i])
pref_dist_temp[local_role_assignment[i][i][0]] = -1
for j in range(swarm_size):
if len(local_robot_assignment[i][j]) != 0:
pref_dist_temp[j] = -1
role_new = np.argmax(pref_dist_temp)
if pref_dist_temp[role_new] < 0:
print("error, robot {} has no available role".format(i))
sys.exit()
local_robot_assignment[i][role_old].remove(i)
local_robot_assignment[i][role_new].append(i)
local_role_assignment[i][i][0] = role_new
local_role_assignment[i][i][1] = pref_dist[i][role_new]
local_role_assignment[i][i][2] = iter_count
transmit_flag[i][i] = True
transmission_total = 0
for transmitter in range(swarm_size):
for source in range(swarm_size):
if transmit_flag[transmitter][source]:
transmit_flag[transmitter][source] = False
message_temp = [source, local_role_assignment[transmitter][source][0],
local_role_assignment[transmitter][source][1],
local_role_assignment[transmitter][source][2]]
for target in neighbors_send[source][transmitter]:
message_rx[target].append(message_temp)
transmission_total = transmission_total + 1
for i in range(swarm_size):
if not scheme_converged[i]:
converged = True
for j in range(swarm_size):
if len(local_robot_assignment[i][j]) != 1:
converged = False
break
if converged:
scheme_converged[i] = True
persist_robots = []
for i in range(swarm_size):
if i in yield_robots: continue
if len(local_robot_assignment[i][local_role_assignment[i][i][0]]) > 1:
persist_robots.append(i)
for i in range(swarm_size):
for j in range(i+1, swarm_size):
if conn_table[i,j]:
pygame.draw.line(screen, color_black, disp_poses[i], disp_poses[j],
conn_width_thin_consensus)
for i in range(swarm_size):
pygame.draw.circle(screen, color_black, disp_poses[i], robot_size_consensus, 0)
for i in persist_robots:
pygame.draw.circle(screen, distinct_color_set[role_color[local_role_assignment[i][i][0]]],
disp_poses[i], robot_size_consensus, 0)
for i in range(swarm_size):
if scheme_converged[i]:
pygame.draw.circle(screen, color_black, disp_poses[i],
robot_ring_size, 1)
pygame.display.update()
for _ in range(3):
for i in range(len(yield_robots)):
pygame.draw.circle(screen, distinct_color_set[role_color[yield_roles[i]]],
disp_poses[yield_robots[i]], robot_size_consensus, 0)
pygame.display.update()
pygame.time.delay(flash_delay)
for i in range(len(yield_robots)):
pygame.draw.circle(screen, color_black,
disp_poses[yield_robots[i]], robot_size_consensus, 0)
pygame.display.update()
pygame.time.delay(flash_delay)
all_converged = scheme_converged[0]
for i in range(1, swarm_size):
all_converged = all_converged and scheme_converged[i]
if not all_converged: break
if all_converged:
for i in range(swarm_size):
assignment_scheme[i] = local_role_assignment[0][i][0]
print("")
print("simulation 3 is finished")
if manual_mode: raw_input("<Press Enter to continue>")
print("")
break
print("##### simulation 4: loop formation #####")
robot_states = np.array([-1 for i in range(swarm_size)])
n1_life_lower = 2
n1_life_upper = 6
robot_n1_lives = np.random.uniform(n1_life_lower, n1_life_upper, swarm_size)
robot_oris = np.random.rand(swarm_size) * 2 * math.pi - math.pi
robot_key_neighbors = [[] for i in range(swarm_size)]
groups = {}
life_incre = 5
group_id_upper = swarm_size
robot_group_ids = np.array([-1 for i in range(swarm_size)])
step_moving_dist = 0.05
destination_error = 0.1
mov_vec_ratio = 0.5
linear_const = 1.0
bend_const = 0.8
disp_coef = 0.5
space_good_thres = desired_space * 0.85
sim_haulted = False
time_last = pygame.time.get_ticks()
time_now = time_last
frame_period = 50
sim_freq_control = True
iter_count = 0
print("swarm robots are forming an ordered loop ...")
loop_formed = False
ending_period = 1.0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("program exit in simulation 4")
sys.exit()
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
sim_haulted = not sim_haulted
if sim_haulted: continue
if sim_freq_control:
time_now = pygame.time.get_ticks()
if (time_now - time_last) > frame_period:
time_last = time_now
else:
continue
iter_count = iter_count + 1
st_n1to0 = []
st_gton1 = []
st_0to1 = {}
st_0to2 = {}
st_1to2 = {}
dist_conn_update()
for i in range(swarm_size):
if robot_states[i] == -1:
if robot_n1_lives[i] < 0:
st_n1to0.append(i)
else:
if len(conn_lists[i]) == 0: continue
state2_list = []
state1_list = []
for j in conn_lists[i]:
if robot_states[j] == 2:
state2_list.append(j)
elif robot_states[j] == 1:
state1_list.append(j)
if len(state2_list) + len(state1_list) != 0:
groups_local, group_id_max = S14_robot_grouping(
state2_list + state1_list, robot_group_ids, groups)
if len(groups_local.keys()) > 1:
for group_id_temp in groups_local.keys():
if ((group_id_temp != group_id_max) and
(group_id_temp not in st_gton1)):
st_gton1.append(group_id_temp)
else:
if len(state2_list) != 0:
robot_closest = S14_closest_robot(i, state2_list)
vect_temp = robot_poses[i] - robot_poses[robot_closest]
robot_oris[i] = math.atan2(vect_temp[1], vect_temp[0])
elif robot_states[i] == 0:
if len(conn_lists[i]) == 0: continue
state2_list = []
state1_list = []
state0_list = []
for j in conn_lists[i]:
if robot_states[j] == 2:
state2_list.append(j)
elif robot_states[j] == 1:
state1_list.append(j)
elif robot_states[j] == 0:
state0_list.append(j)
state2_quantity = len(state2_list)
state1_quantity = len(state1_list)
state0_quantity = len(state0_list)
if state2_quantity + state1_quantity > 1:
groups_local, group_id_max = S14_robot_grouping(state2_list+state1_list,
robot_group_ids, groups)
for group_id_temp in groups_local.keys():
if (group_id_temp != group_id_max) and (group_id_temp not in st_gton1):
st_gton1.append(group_id_temp)
if state2_quantity != 0:
if state2_quantity == 1:
st_0to1[i] = robot_group_ids[state2_list[0]]
robot_key_neighbors[i] = [state2_list[0]]
else:
groups_local, group_id_max = S14_robot_grouping(state2_list,
robot_group_ids, groups)
robot_closest = S14_closest_robot(i, groups_local[group_id_max])
st_0to1[i] = group_id_max
robot_key_neighbors[i] = [robot_closest]
elif state0_quantity != 0:
st_0to2[i] = S14_closest_robot(i, state0_list)
elif (robot_states[i] == 1) or (robot_states[i] == 2):
state12_list = []
has_other_group = False
host_group_id = robot_group_ids[i]
for j in conn_lists[i]:
if (robot_states[j] == 1) or (robot_states[j] == 2):
state12_list.append(j)
if robot_group_ids[j] != host_group_id:
has_other_group = True
if has_other_group:
groups_local, group_id_max = S14_robot_grouping(state12_list,
robot_group_ids, groups)
for group_id_temp in groups_local.keys():
if (group_id_temp != group_id_max) and (group_id_temp not in st_gton1):
st_gton1.append(group_id_temp)
if robot_states[i] == 1:
current_key = robot_key_neighbors[i][0]
next_key = robot_key_neighbors[current_key][-1]
if next_key in conn_lists[i]:
role_i = assignment_scheme[i]
role_current_key = assignment_scheme[current_key]
role_next_key = assignment_scheme[next_key]
if len(robot_key_neighbors[current_key]) == 1:
vect_temp = robot_poses[next_key] - robot_poses[current_key]
vect_i = robot_poses[i] - robot_poses[current_key]
side_value = np.cross(vect_i, vect_temp)
if side_value > 0:
if role_next_key > role_current_key:
if (role_i < role_current_key) or (role_i > role_next_key):
robot_key_neighbors[i] = [next_key]
else:
if current_key in st_1to2.keys():
st_1to2[current_key].append(i)
else:
st_1to2[current_key] = [i]
else:
if (role_i < role_current_key) and (role_i > role_next_key):
robot_key_neighbors[i] = [next_key]
else:
if current_key in st_1to2.keys():
st_1to2[current_key].append(i)
else:
st_1to2[current_key] = [i]
else:
pass
else:
if role_next_key > role_current_key:
if (role_i < role_current_key) or (role_i > role_next_key):
robot_key_neighbors[i] = [next_key]
else:
if current_key in st_1to2.keys():
st_1to2[current_key].append(i)
else:
st_1to2[current_key] = [i]
else:
if (role_i < role_current_key) and (role_i > role_next_key):
robot_key_neighbors[i] = [next_key]
else:
if current_key in st_1to2.keys():
st_1to2[current_key].append(i)
else:
st_1to2[current_key] = [i]
for group_id_temp in groups.keys():
if groups[group_id_temp][1] < 0:
if group_id_temp not in st_gton1:
st_gton1.append(group_id_temp)
for left_key in st_1to2.keys():
right_key = robot_key_neighbors[left_key][-1]
role_left_key = assignment_scheme[left_key]
role_right_key = assignment_scheme[right_key]
joiner = -1
if len(st_1to2[left_key]) == 1:
joiner = st_1to2[left_key][0]
else:
joiner_list = st_1to2[left_key]
role_dist_min = swarm_size
for joiner_temp in joiner_list:
role_joiner_temp = assignment_scheme[joiner_temp]
role_dist_temp = role_joiner_temp - role_left_key
if role_dist_temp < 0:
role_dist_temp = role_dist_temp + swarm_size
if role_dist_temp < role_dist_min:
joiner = joiner_temp
role_dist_min = role_dist_temp
group_id_temp = robot_group_ids[left_key]
robot_states[joiner] = 2
robot_group_ids[joiner] = group_id_temp
robot_key_neighbors[joiner] = [left_key, right_key]
if len(robot_key_neighbors[left_key]) == 1:
robot_key_neighbors[left_key] = [right_key, joiner]
robot_key_neighbors[right_key] = [joiner, left_key]
else:
robot_key_neighbors[left_key][1] = joiner
robot_key_neighbors[right_key][0] = joiner
for joiner in st_0to1.keys():
group_id_temp = st_0to1[joiner]
robot_states[joiner] = 1
robot_group_ids[joiner] = group_id_temp
groups[group_id_temp][0].append(joiner)
groups[group_id_temp][1] = groups[group_id_temp][1] + life_incre
while len(st_0to2.keys()) != 0:
pair0 = st_0to2.keys()[0]
pair1 = st_0to2[pair0]
st_0to2.pop(pair0)
if (pair1 in st_0to2.keys()) and (st_0to2[pair1] == pair0):
st_0to2.pop(pair1)
if robot_seeds[pair0] or robot_seeds[pair1]:
group_id_temp = np.random.randint(0, group_id_upper)
while group_id_temp in groups.keys():
group_id_temp = np.random.randint(0, group_id_upper)
robot_states[pair0] = 2
robot_states[pair1] = 2
robot_group_ids[pair0] = group_id_temp
robot_group_ids[pair1] = group_id_temp
robot_key_neighbors[pair0] = [pair1]
robot_key_neighbors[pair1] = [pair0]
groups[group_id_temp] = [[pair0, pair1], life_incre*2, False]
for group_id_temp in st_gton1:
for robot_temp in groups[group_id_temp][0]:
robot_states[robot_temp] = -1
robot_n1_lives[robot_temp] = np.random.uniform(n1_life_lower, n1_life_upper)
robot_group_ids[robot_temp] = -1
robot_oris[robot_temp] = np.random.rand() * 2 * math.pi - math.pi
robot_key_neighbors[robot_temp] = []
groups.pop(group_id_temp)
for robot_temp in st_n1to0:
robot_states[robot_temp] = 0
for group_id_temp in groups.keys():
if len(groups[group_id_temp][0]) > swarm_size/2.0:
groups[group_id_temp][2] = True
else:
groups[group_id_temp][2] = False
robot_poses_t = np.copy(robot_poses)
no_state1_robot = True
for i in range(swarm_size):
if robot_states[i] == 1:
no_state1_robot = False
center = robot_key_neighbors[i][0]
if dist_table[i,center] > (desired_space + step_moving_dist):
robot_oris[i] = math.atan2(robot_poses_t[center,1] - robot_poses_t[i,1],
robot_poses_t[center,0] - robot_poses_t[i,0])
elif (dist_table[i,center] + step_moving_dist) < desired_space:
robot_oris[i] = math.atan2(robot_poses_t[i,1] - robot_poses_t[center,1],
robot_poses_t[i,0] - robot_poses_t[center,0])
else:
robot_oris[i] = math.atan2(robot_poses_t[i,1] - robot_poses_t[center,1],
robot_poses_t[i,0] - robot_poses_t[center,0])
int_angle_temp = math.acos(np.around((math.pow(dist_table[i,center],2) +
math.pow(step_moving_dist,2) - math.pow(desired_space,2)) /
(2.0*dist_table[i,center]*step_moving_dist)))
robot_oris[i] = reset_radian(robot_oris[i] + (math.pi - int_angle_temp))
elif robot_states[i] == 2:
if len(robot_key_neighbors[i]) == 1:
j = robot_key_neighbors[i][0]
if abs(dist_table[i,j] - desired_space) < destination_error:
continue
else:
if dist_table[i,j] > desired_space:
robot_oris[i] = math.atan2(robot_poses_t[j,1] - robot_poses_t[i,1],
robot_poses_t[j,0] - robot_poses_t[i,0])
else:
robot_oris[i] = math.atan2(robot_poses_t[i,1] - robot_poses_t[j,1],
robot_poses_t[i,0] - robot_poses_t[j,0])
else:
group_id_temp = robot_group_ids[i]
state2_quantity = 0
for robot_temp in groups[group_id_temp][0]:
if robot_states[robot_temp] == 2:
state2_quantity = state2_quantity + 1
desired_angle = math.pi - 2*math.pi / state2_quantity
left_key = robot_key_neighbors[i][0]
right_key = robot_key_neighbors[i][1]
vect_l = (robot_poses_t[left_key] - robot_poses_t[i]) / dist_table[i,left_key]
vect_r = (robot_poses_t[right_key] - robot_poses_t[i]) / dist_table[i,right_key]
vect_lr = robot_poses_t[right_key] - robot_poses_t[left_key]
vect_lr_dist = np.linalg.norm(vect_lr)
vect_in = np.array([-vect_lr[1], vect_lr[0]]) / vect_lr_dist
inter_curr = math.acos(np.dot(vect_l, vect_r))
if np.cross(vect_r, vect_l) < 0:
inter_curr = 2*math.pi - inter_curr
fb_vect = np.zeros(2)
fb_vect = fb_vect + ((dist_table[i,left_key] - desired_space) *
linear_const * vect_l)
fb_vect = fb_vect + ((dist_table[i,right_key] - desired_space) *
linear_const * vect_r)
fb_vect = fb_vect + ((desired_angle - inter_curr) *
bend_const * vect_in)
if (np.linalg.norm(fb_vect)*disp_coef < destination_error and
dist_table[i,left_key] > space_good_thres and
dist_table[i,right_key] > space_good_thres):
continue
else:
robot_oris[i] = math.atan2(fb_vect[1], fb_vect[0])
if (robot_states[i] == -1) or (robot_states[i] == 0):
robot_oris[i] = robot_boundary_check(robot_poses_t[i], robot_oris[i])
robot_poses[i] = robot_poses_t[i] + (step_moving_dist *
np.array([math.cos(robot_oris[i]), math.sin(robot_oris[i])]))
disp_poses_update()
screen.fill(color_white)
for i in range(swarm_size):
if robot_seeds[i]:
color_temp = color_red
else:
color_temp = color_grey
if robot_states[i] == -1:
pygame.draw.circle(screen, color_temp, disp_poses[i],
robot_size_formation, robot_width_empty)
elif robot_states[i] == 0:
pygame.draw.circle(screen, color_temp, disp_poses[i],
robot_size_formation, 0)
text = font.render(str(int(assignment_scheme[i])), True, color_grey)
screen.blit(text, (disp_poses[i,0]+6, disp_poses[i,1]-6))
for group_id_temp in groups.keys():
if groups[group_id_temp][2]:
color_group = color_black
else:
color_group = color_grey
conn_draw_sets = []
for i in groups[group_id_temp][0]:
for j in robot_key_neighbors[i]:
if set([i,j]) not in conn_draw_sets:
pygame.draw.line(screen, color_group, disp_poses[i],
disp_poses[j], conn_width_formation)
conn_draw_sets.append(set([i,j]))
if robot_seeds[i]:
pygame.draw.circle(screen, color_red, disp_poses[i],
robot_size_formation, 0)
else:
pygame.draw.circle(screen, color_group, disp_poses[i],
robot_size_formation, 0)
pygame.display.update()
for i in range(swarm_size):
if robot_states[i] == -1:
robot_n1_lives[i] = robot_n1_lives[i] - frame_period/1000.0
for group_id_temp in groups.keys():
if not groups[group_id_temp][2]:
groups[group_id_temp][1] = groups[group_id_temp][1] - frame_period/1000.0
if not loop_formed:
if ((len(groups.keys()) == 1) and (len(groups.values()[0][0]) == swarm_size)
and no_state1_robot):
loop_formed = True
if loop_formed:
if ending_period <= 0:
print("simulation 4 is finished")
if manual_mode: raw_input("<Press Enter to continue>")
print("")
break
else:
ending_period = ending_period - frame_period/1000.0
print("##### simulation 5: loop reshaping #####")
print("chosen shape {}: {}".format(shape_decision, shape_catalog[shape_decision]))
linear_const = 1.0
bend_const = 0.8
disp_coef = 0.05
x_max, y_max = np.amax(robot_poses, axis=0)
x_min, y_min = np.amin(robot_poses, axis=0)
robot_middle = np.array([(x_max+x_min)/2.0, (y_max+y_min)/2.0])
world_middle = np.array([world_side_length/2.0, world_side_length/2.0])
for i in range(swarm_size):
robot_poses[i] = robot_poses[i] - robot_middle + world_middle
filename = str(swarm_size) + "-" + shape_catalog[shape_decision]
filepath = os.path.join(os.getcwd(), loop_folder, filename)
if os.path.isfile(filepath):
with open(filepath, 'r') as f:
target_poses = pickle.load(f)
else:
print("fail to locate shape file: {}".format(filepath))
sys.exit()
inter_target = np.zeros(swarm_size)
for i in range(swarm_size):
i_l = (i-1)%swarm_size
i_r = (i+1)%swarm_size
vect_l = target_poses[i_l] - target_poses[i]
vect_r = target_poses[i_r] - target_poses[i]
dist_l = np.linalg.norm(vect_l)
dist_r = np.linalg.norm(vect_r)
robot_temp = list(assignment_scheme).index(i)
inter_target[robot_temp] = math.acos(np.around(
np.dot(vect_l, vect_r) / (dist_l * dist_r) ,6))
if np.cross(vect_r, vect_l) < 0:
inter_target[robot_temp] = 2*math.pi - inter_target[robot_temp]
for i in range(swarm_size):
if len(robot_key_neighbors[i]) != 2:
print("state 1 robot not merged in yet")
sys.exit()
else:
i_left = robot_key_neighbors[i][0]
i_right = robot_key_neighbors[i][1]
role_i = assignment_scheme[i]
role_i_left = assignment_scheme[i_left]
role_i_right = assignment_scheme[i_right]
if (((role_i-role_i_left)%swarm_size != 1) or
((role_i_right-role_i)%swarm_size != 1)):
print("loop formed with incorrect order")
sys.exit()
inter_err_thres = 0.1
sim_haulted = False
time_last = pygame.time.get_ticks()
time_now = time_last
frame_period = 100
sim_freq_control = True
iter_count = 0
print("loop is reshaping to " + shape_catalog[shape_decision] + " ...")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("program exit in simulation 5")
sys.exit()
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
sim_haulted = not sim_haulted
if sim_haulted: continue
if sim_freq_control:
time_now = pygame.time.get_ticks()
if (time_now - time_last) > frame_period:
time_last = time_now
else:
continue
iter_count = iter_count + 1
robot_poses_t = np.copy(robot_poses)
inter_curr = np.zeros(swarm_size)
for i in range(swarm_size):
i_l = robot_key_neighbors[i][0]
i_r = robot_key_neighbors[i][1]
vect_l = robot_poses_t[i_l] - robot_poses_t[i]
vect_r = robot_poses_t[i_r] - robot_poses_t[i]
vect_lr = robot_poses_t[i_r] - robot_poses_t[i_l]
dist_l = np.linalg.norm(vect_l)
dist_r = np.linalg.norm(vect_r)
dist_lr = np.linalg.norm(vect_lr)
u_vect_l = vect_l / dist_l
u_vect_r = vect_r / dist_r
u_vect_in = np.array([-vect_lr[1], vect_lr[0]]) / dist_lr
inter_curr[i] = math.acos(np.around(
np.dot(vect_l, vect_r) / (dist_l * dist_r), 6))
if np.cross(vect_r, vect_l) < 0:
inter_curr[i] = 2*math.pi - inter_curr[i]
fb_vect = np.zeros(2)
fb_vect = fb_vect + (dist_l - desired_space) * linear_const * u_vect_l
fb_vect = fb_vect + (dist_r - desired_space) * linear_const * u_vect_r
fb_vect = fb_vect + (inter_target[i] - inter_curr[i]) * bend_const * u_vect_in
robot_poses[i] = robot_poses_t[i] + disp_coef * fb_vect
disp_poses_update()
screen.fill(color_white)
for i in range(swarm_size):
pygame.draw.circle(screen, color_black, disp_poses[i], robot_size_formation, 0)
pygame.draw.line(screen, color_black, disp_poses[i],
disp_poses[robot_key_neighbors[i][1]], conn_width_formation)
pygame.display.update()
inter_err_max = max(np.absolute(inter_curr - inter_target))
if inter_err_max < inter_err_thres:
print("simulation 5 is finished")
if manual_mode: raw_input("<Press Enter to continue>")
print("")
break