3232
3333class Particle :
3434
35- def __init__ (self ):
35+ def __init__ (self , N_LM ):
3636 self .w = 1.0 / N_PARTICLE
3737 self .x = 0.0
3838 self .y = 0.0
3939 self .yaw = 0.0
40+ self .lm = np .zeros ((N_LM , 2 ))
41+
42+
43+ def normalize_weight (particles ):
44+
45+ sumw = sum ([particles [ip ].w for ip in range (N_PARTICLE )])
46+
47+ for i in range (N_PARTICLE ):
48+ particles [i ].w = particles [i ].w / sumw
49+
50+ return particles
4051
4152
4253def calc_final_state (particles ):
4354
55+ particles = normalize_weight (particles )
56+
4457 xEst = np .zeros ((STATE_SIZE , 1 ))
4558
4659 for i in range (N_PARTICLE ):
@@ -69,19 +82,67 @@ def predict_particles(particles, u):
6982 return particles
7083
7184
72- def update_with_observation (particle , z ):
85+ def add_new_lm (particle , z ):
86+
87+ r = z [0 , 0 ]
88+ b = z [0 , 1 ]
89+ lm_id = int (z [0 , 2 ])
90+
91+ s = math .sin (particle .yaw + b )
92+ c = math .cos (particle .yaw + b )
93+
94+ particle .lm [lm_id , 0 ] = particle .x + r * c
95+ particle .lm [lm_id , 1 ] = particle .y + r * s
7396
7497 return particle
7598
7699
100+ def compute_weight (particle , z ):
101+
102+ lm_id = int (z [0 , 2 ])
103+
104+ lmxy = np .matrix (particle .lm [lm_id , :])
105+ zxy = z [0 , 0 :2 ]
106+ # print(lmxy)
107+ # print(zxy)
108+
109+ dx = (lmxy - zxy ).T
110+ S = np .eye (2 )
111+
112+ num = math .exp (- 0.5 * dx .T * np .linalg .inv (S ) * dx )
113+ den = 2.0 * math .pi * math .sqrt (np .linalg .det (S ))
114+
115+ w = num / den
116+
117+ return w
118+
119+
120+ def update_with_observation (particles , z ):
121+
122+ for iz in range (len (z [:, 0 ])):
123+
124+ lmid = int (z [iz , 2 ])
125+
126+ for ip in range (N_PARTICLE ):
127+ # new landmark
128+ if abs (particles [ip ].lm [lmid , 0 ]) <= 0.1 :
129+ particles [ip ] = add_new_lm (particles [ip ], z [iz , :])
130+ # known landmark
131+ else :
132+ w = compute_weight (particles [ip ], z [iz , :]) # w = p(z_k | x_k)
133+ particles [ip ].w = particles [ip ].w * w
134+ # particles(i)= feature_update(particles(i), zf, idf, R)
135+
136+ return particles
137+
138+
77139def fast_slam (particles , PEst , u , z ):
78140
79141 # Predict
80142 particles = predict_particles (particles , u )
81143
82144 # Observation
83- for i in range (N_PARTICLE ):
84- particles [i ] = update_with_observation (particles [i ], z )
145+ particles = update_with_observation (particles , z )
85146
86147 xEst = calc_final_state (particles )
87148
@@ -163,7 +224,7 @@ def get_LM_Pos_from_state(x, ind):
163224
164225def search_correspond_LM_ID (xAug , PAug , zi ):
165226 """
166- Landmark association with Mahalanobis distance
227+ Landmark association with Nearest Neighbor
167228 """
168229
169230 nLM = calc_n_LM (xAug )
@@ -203,6 +264,7 @@ def main():
203264 [15.0 , 10.0 ],
204265 [3.0 , 15.0 ],
205266 [- 5.0 , 20.0 ]])
267+ N_LM = RFID .shape [0 ]
206268
207269 # State Vector [x y yaw v]'
208270 xEst = np .matrix (np .zeros ((STATE_SIZE , 1 )))
@@ -216,7 +278,7 @@ def main():
216278 hxTrue = xTrue
217279 hxDR = xTrue
218280
219- particles = [Particle () for i in range (N_PARTICLE )]
281+ particles = [Particle (N_LM ) for i in range (N_PARTICLE )]
220282
221283 while SIM_TIME >= time :
222284 time += DT
0 commit comments