-
Notifications
You must be signed in to change notification settings - Fork 78
/
motion.py
159 lines (123 loc) · 6.14 KB
/
motion.py
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
153
154
155
156
157
158
159
'''
file that contains all function related to population mobility
and related computations
'''
import numpy as np
def update_positions(population):
'''update positions of all people
Uses heading and speed to update all positions for
the next time step
Keyword arguments
-----------------
population : ndarray
the array containing all the population information
'''
#update positions
#x
population[:,1] = population[:,1] + (population[:,3] * population[:,5])
#y
population[:,2] = population[:,2] + (population [:,4] * population[:,5])
return population
def out_of_bounds(population, xbounds, ybounds):
'''checks which people are about to go out of bounds and corrects
Function that updates headings of individuals that are about to
go outside of the world boundaries.
Keyword arguments
-----------------
population : ndarray
the array containing all the population information
xbounds, ybounds : list or tuple
contains the lower and upper bounds of the world [min, max]
'''
#update headings and positions where out of bounds
#update x heading
#determine number of elements that need to be updated
shp = population[:,3][(population[:,1] <= xbounds[:,0]) &
(population[:,3] < 0)].shape
population[:,3][(population[:,1] <= xbounds[:,0]) &
(population[:,3] < 0)] = np.clip(np.random.normal(loc = 0.5,
scale = 0.5/3,
size = shp),
a_min = 0.05, a_max = 1)
shp = population[:,3][(population[:,1] >= xbounds[:,1]) &
(population[:,3] > 0)].shape
population[:,3][(population[:,1] >= xbounds[:,1]) &
(population[:,3] > 0)] = np.clip(-np.random.normal(loc = 0.5,
scale = 0.5/3,
size = shp),
a_min = -1, a_max = -0.05)
#update y heading
shp = population[:,4][(population[:,2] <= ybounds[:,0]) &
(population[:,4] < 0)].shape
population[:,4][(population[:,2] <= ybounds[:,0]) &
(population[:,4] < 0)] = np.clip(np.random.normal(loc = 0.5,
scale = 0.5/3,
size = shp),
a_min = 0.05, a_max = 1)
shp = population[:,4][(population[:,2] >= ybounds[:,1]) &
(population[:,4] > 0)].shape
population[:,4][(population[:,2] >= ybounds[:,1]) &
(population[:,4] > 0)] = np.clip(-np.random.normal(loc = 0.5,
scale = 0.5/3,
size = shp),
a_min = -1, a_max = -0.05)
return population
def update_randoms(population, pop_size, speed=0.01, heading_update_chance=0.02,
speed_update_chance=0.02, heading_multiplication=1,
speed_multiplication=1):
'''updates random states such as heading and speed
Function that randomized the headings and speeds for population members
with settable odds.
Keyword arguments
-----------------
population : ndarray
the array containing all the population information
pop_size : int
the size of the population
heading_update_chance : float
the odds of updating the heading of each member, each time step
speed_update_chance : float
the oodds of updating the speed of each member, each time step
heading_multiplication : int or float
factor to multiply heading with (default headings are between -1 and 1)
speed_multiplication : int or float
factor to multiply speed with (default speeds are between 0.0001 and 0.05
speed : int or float
mean speed of population members, speeds will be taken from gaussian distribution
with mean 'speed' and sd 'speed / 3'
'''
#randomly update heading
#x
update = np.random.random(size=(pop_size,))
shp = update[update <= heading_update_chance].shape
population[:,3][update <= heading_update_chance] = np.random.normal(loc = 0,
scale = 1/3,
size = shp) * heading_multiplication
#y
update = np.random.random(size=(pop_size,))
shp = update[update <= heading_update_chance].shape
population[:,4][update <= heading_update_chance] = np.random.normal(loc = 0,
scale = 1/3,
size = shp) * heading_multiplication
#randomize speeds
update = np.random.random(size=(pop_size,))
shp = update[update <= heading_update_chance].shape
population[:,5][update <= heading_update_chance] = np.random.normal(loc = speed,
scale = speed / 3,
size = shp) * speed_multiplication
population[:,5] = np.clip(population[:,5], a_min=0.0001, a_max=0.05)
return population
def get_motion_parameters(xmin, ymin, xmax, ymax):
'''gets destination center and wander ranges
Function that returns geometric parameters of the destination
that the population members have set.
Keyword arguments:
------------------
xmin, ymin, xmax, ymax : int or float
lower and upper bounds of the destination area set.
'''
x_center = xmin + ((xmax - xmin) / 2)
y_center = ymin + ((ymax - ymin) / 2)
x_wander = (xmax - xmin) / 2
y_wander = (ymax - ymin) / 2
return x_center, y_center, x_wander, y_wander