-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMAPF.m
144 lines (104 loc) · 5.41 KB
/
MAPF.m
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
classdef MAPF
%APF Summary of this class goes here
% Detailed explanation goes here
properties
drones
% Feild data sets
timeUnit = 1/25;
stepsize = 0.2;
attBound = 5;
repDist = 1;
threshold = 0.2;
% Coefficients
epsilon = 0.5;
etaR = 0.2;
etaV = 0.2;
util;
end
methods
function self = MAPF(drones)
self.drones = drones;
self.util = Utility();
%self.fAttMax = norm(self.attraction(startPt,target,self.attBound,self.epsilon));
end
% Compute the attractive force
function f_att = attraction(self,drone,distBound,epsilon)
dis = norm(drone.position-drone.target);
% To prevent attraction force grown too big when it's far from target
% Set an upper bound to the arraction force
if dis <= distBound
fx = epsilon * (drone.target(1) - drone.position(1));
fy = epsilon * (drone.target(2) - drone.position(2));
fz = epsilon * (drone.target(3) - drone.position(3));
else
fx = distBound * epsilon * (drone.target(1) - drone.position(1)) / dis;
fy = distBound * epsilon * (drone.target(2) - drone.position(2)) / dis;
fz = distBound * epsilon * (drone.target(3) - drone.position(3)) / dis;
end
% Return a the attraction force vector
f_att = [fx, fy, fz];
end
% Calculate the total Velocity-Repulsive force
function f_VRep = repulsion(self,drone,obstacles,affectDistance,etaR, etaV)
f_VRep = [0, 0, 0]; %Initialize the force
distToTarget = norm(drone.position - drone.target);
n=2; %n is an arbitrary real number which is greater than zero
for i = 1 : size(obstacles,2)
% skip the drone itself
if drone.id == i
continue;
end
distToObst = norm(drone.position-obstacles(i).position);
%Drone is affecting by abstacle's repulsivefield
if distToObst <= affectDistance ...
&& self.util.getCos(norm(drone.velocity - obstacles(i).velocity), norm(drone.position - obstacles(i).position)) > 0
% Calculate the repulsive force
a = self.util.differential(drone.position,obstacles(i).position);
b = self.util.differential(drone.position,drone.target);
fRepByObst = etaR * (1/distToObst - 1/affectDistance) * distToTarget^n/distToObst^2 * -1 * self.util.differential(drone.position,obstacles(i).position)...
+ (n/2) * etaR * (1/distToObst - 1/affectDistance)^2 * distToTarget^(n-1) * -1 * self.util.differential(drone.position,drone.target);
% Calculate the velocity repulsive force
fVByObst = etaV * norm(obstacles(i).velocity - drone.velocity) * self.util.differential(obstacles(i).position, drone.position);
f_VRep = f_VRep + fRepByObst ;%+ fVByObst;
%fprintf('\naffect by [%d,%d,%d], with rep of [%f,%f,%f] and Vrep of [%f,%f,%f]\n',obstacles(i).position, fRepByObst,fVByObst);
end
end
end
%Calculate the next step for current drone
% Consider add up kinematicConstrant later
function [nextPos,actualV] = getNextStep(self,drone,drones)
force = self.getTotalForce(drone,drones);
% The maximum speed the drone can reach is corelated to force, but was constarined by vMAx
targetV = drone.vMax * force;
targetVValue = norm(targetV);
if targetVValue > drone.vMax
targetV = targetV * (drone.vMax/targetVValue);
targetVValue = drone.vMax;
end
accTime = min(abs(targetVValue - norm(drone.velocity))/drone.accMax, self.timeUnit);
% check if the drone is speeding up or slowing down
if targetVValue < norm(drone.velocity)
flag = -1;
else
flag = 1;
end
actualVValue = norm(drone.velocity) + drone.accMax * accTime * flag;
actualV = (actualVValue/targetVValue) * targetV;
nextPos = drone.position + 0.5 * (actualV + drone.velocity) * accTime + actualV * (self.timeUnit-accTime);
fprintf('next Pos [%f,%f,%f] with speed %f \n', nextPos, actualVValue);
end
% Calculate the total force of the field on the drone
function f_total = getTotalForce(self,drone,drones)
f_att = self.attraction(drone,self.attBound,self.epsilon);
f_rep = self.repulsion(drone,drones,self.repDist,self.etaR, self.etaV);
f_total = f_att + f_rep;
fprintf('total force [%f,%f,%f] \n', f_total);
%f_total = self.util.getUnitVec(f_total);
f_total = self.util.getNormalized(self.fAttMax, f_total);
end
function saveCSV(self,folder)
writematrix(self.path, ['./',folder,'/pathMatrix'],'Delimiter',',');
writematrix()
end
end
end