-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdemo_unicycle_coordination_circle.py
More file actions
152 lines (121 loc) · 3.82 KB
/
Copy pathdemo_unicycle_coordination_circle.py
File metadata and controls
152 lines (121 loc) · 3.82 KB
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import sys
# Add paths
sys.path.insert(1, './GNC')
sys.path.insert(1, './graphics')
sys.path.insert(1, './postproc')
sys.path.insert(1, './vehicles')
import pygame
import matplotlib.pyplot as pl
import matplotlib.colors as mcolors
import drawmisc
import agents as ag
import numpy as np
from numpy import linalg as la
import logpostpro as lp
import gvf
# setup simulation
animation = 0
if animation:
WIDTH = 1000
HEIGHT = 1000
CENTERX = WIDTH/2
CENTERY = WIDTH/2
BLACK = ( 0, 0, 0)
size = [WIDTH, HEIGHT]
screen = pygame.display.set_mode(size)
# Network
num_of_agents = 3
list_of_agents = []
list_of_edges = [] # For the coordination on the circle
for i in range(num_of_agents-1):
list_of_edges.append((i,i+1)) # Daisy chain network topology
desired_inter_vehicle_theta = (2*np.pi/num_of_agents)*np.ones((len(list_of_edges),1))
theta_vehicles = np.zeros((num_of_agents,1))
k_coord = 100
# Incidence matrix
B = np.zeros((num_of_agents, len(list_of_edges)))
for idx,edge in enumerate(list_of_edges):
B[edge[0],idx] = 1
B[edge[1],idx] = -1
B_dir = np.zeros((num_of_agents, len(list_of_edges)))
for idx,edge in enumerate(list_of_edges):
B_dir[edge[0],idx] = 1
B_dir[edge[1],idx] = 0
# Directed vs Undirected graph. They have different convergence properties
# If you want to control with an undirected graph, then uncomment the following.
B_dir = B
for i in range(num_of_agents):
theta_o = np.pi - (2*np.pi)*np.random.rand(1);
list_of_agents.append(ag.AgentUnicycle(list(pygame.colordict.THECOLORS.items())[np.random.randint(0,657)][1], i, 1000*np.random.rand(2,1), 60*np.array([[np.cos(theta_o[0])],[np.sin(theta_o[0])]])))
for agent in list_of_agents:
agent.traj_draw = True
# GVF
ke_circle = 5e-5
kd_circle = 60
xo = 500 # Circle's center
yo = 500
ro = 150 # radius
#
direction = -1 # Clock or counter-clock wise. This defines what angular velocity is positive
# run simulation
time = 0
end_time = 100
if animation:
pygame.init()
clock = pygame.time.Clock()
fps = 50
dt = 1.0/fps
else:
dt = 0.02
runsim = True
while(runsim):
if animation:
screen.fill(BLACK)
us = 0 # We keep constant velocity
# Coordination algorithm on the circle (calculated in a compact way)
for idx,agent in enumerate(list_of_agents):
theta_vehicles[idx] = np.arctan2(agent.pos[1]-yo, agent.pos[0]-xo)
inter_theta = B.transpose().dot(theta_vehicles)
error_theta = inter_theta - desired_inter_vehicle_theta
if np.size(error_theta) > 1:
for i in range(0, np.size(error_theta)):
if error_theta[i] > np.pi:
error_theta[i] = error_theta[i] - 2*np.pi
elif error_theta[i] <= -np.pi:
error_theta[i] = error_theta[i] + 2*np.pi
else:
if error_theta > np.pi:
error_theta = error_theta - 2*np.pi
elif error_theta <= -np.pi:
error_theta = error_theta + 2*np.pi
dr = -k_coord*B_dir.dot(np.sin(error_theta))
dr = direction*dr
# Guiding vector field
for idx,agent in enumerate(list_of_agents):
if animation:
agent.draw(screen)
circle_path = gvf.Path_gvf_circle(xo, yo, ro+dr[idx])
ut = gvf.gvf_control_2D_unicycle(agent.pos, agent.vel, ke_circle, kd_circle, circle_path, direction)
agent.step_dt(us, ut, dt)
if animation:
clock.tick(fps)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
endtime = pygame.time.get_ticks()
pygame.quit()
runsim = False
else:
time = time + dt
if time > end_time:
runsim = False
# Postprocessing
fig = pl.figure(0)
ax = fig.add_subplot(111)
for agent in list_of_agents:
lp.plot_position(ax, agent)
ax.axis("equal")
ax.grid
#circle = pl.Circle((xo, yo), ro, color='r')
#ax.add_patch(circle)
pl.show()