Skip to content

Commit 2362158

Browse files
authored
Merge pull request #3 from ukleon123/school
School
2 parents 2cea22e + 3d3c72c commit 2362158

16 files changed

Lines changed: 471 additions & 131 deletions

controllers/On_Simulation/DWA/dwa.py

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ def _calc_dynamic_window(self, x):
5858
Vd = [
5959
x[3] - self.max_accel * self.dt,
6060
x[3] + self.max_accel * self.dt,
61-
x[4] - self.max_delta_yaw_rate * self.dt,
62-
x[4] + self.max_delta_yaw_rate * self.dt
61+
-self.max_delta_yaw_rate * self.dt,
62+
self.max_delta_yaw_rate * self.dt
6363
]
6464

6565
# Final dynamic window (intersection of constraints)
@@ -93,6 +93,8 @@ def _calc_control_and_trajectory(self, x, dw, goal, obstacles):
9393

9494
valid_trajectories = 0
9595

96+
# print(f"[DEBUG] 현재: x={x[0]:.2f}, y={x[1]:.2f}, yaw={x[2]:.2f}") # debug
97+
9698
# Sample velocities in dynamic window
9799
for v in np.arange(dw[0], dw[1], self.v_resolution):
98100

@@ -103,12 +105,16 @@ def _calc_control_and_trajectory(self, x, dw, goal, obstacles):
103105

104106
for omega in omegas:
105107

108+
# print("=====") #debug
109+
106110
# Predict trajectory
107111
trajectory = self._predict_trajectory(x_init, v, omega)
108112

109113
# Calculate costs
110114
obstacle_cost = self._calc_obstacle_cost(trajectory, obstacles)
111-
115+
if obstacle_cost == 0.0:
116+
continue
117+
112118
speed_cost = self._calc_speed_cost(trajectory)
113119
goal_cost = self._calc_goal_cost(trajectory, goal)
114120
curvature_cost = self._calc_curvature_cost(trajectory, goal)
@@ -120,17 +126,23 @@ def _calc_control_and_trajectory(self, x, dw, goal, obstacles):
120126
self.obstacle_cost_gain * obstacle_cost +
121127
self.curvature_cost_gain * curvature_cost
122128
)
123-
if obstacle_cost == 0.0:
124-
continue
129+
125130
# Skip collision trajectories
126131
valid_trajectories += 1
127-
132+
133+
134+
# print(f"omega: {omega:.4f}, total_cost: {total_cost:.4f}") #debug
135+
# print(f"trajectory: {trajectory[-1, 0]}, {trajectory[-1, 1]}, {trajectory[-1, 2]}") #debug
136+
#print(f"costs: speed: {speed_cost:.4f}, goal: {goal_cost:.4f}, obstacle: {obstacle_cost:.4f}, curvature: {curvature_cost:.4f}") #debug
137+
128138
# Update best trajectory
129139
if total_cost > max_cost:
130140
max_cost = total_cost
131141
self.best_u = [v, omega]
132142
best_trajectory = trajectory
133-
143+
144+
# print(f"best u: {self.best_u[0]}, {self.best_u[1]} = max_cost: {max_cost:.4f}") #debug
145+
# print("--------------------------------------------") #debug
134146
return self.best_u, best_trajectory
135147

136148
def _predict_trajectory(self, x_init, v, omega):
@@ -152,29 +164,50 @@ def _predict_trajectory(self, x_init, v, omega):
152164

153165
return trajectory
154166

167+
155168
def _calc_speed_cost(self, trajectory):
156169
"""Speed cost - encourages higher speeds (normalized)"""
157170
if len(trajectory) == 0:
158171
return 0.0
159172
# Normalize speed cost (higher speed = higher cost value for maximization)
160173
return trajectory[-1, 3] / self.max_speed
161174

162-
def _calc_goal_cost(self, trajectory, goal):
163-
"""Goal cost - encourages moving toward goal"""
175+
def _calc_goal_cost(self, trajectory, goal, alpha=0.3, beta=0.7):
176+
"""
177+
혼합 goal cost 계산 함수 (높을수록 좋은 값)
178+
- alpha: 방향 cost 가중치
179+
- beta: 거리 cost 가중치
180+
"""
164181
if len(trajectory) == 0:
165-
return 1.0
166-
167-
# Distance to goal from final trajectory point
168-
dx = goal[0] - trajectory[-1, 0]
169-
dy = goal[1] - trajectory[-1, 1]
170-
171-
# Heading error - angle between robot heading and direction to goal
182+
return 1.0 # 최악의 경우
183+
184+
x, y, theta = trajectory[-1, 0], trajectory[-1, 1], trajectory[-1, 2]
185+
186+
dx = goal[0] - x
187+
dy = goal[1] - y
188+
distance = np.hypot(dx, dy)
189+
#print(f"[DEBUG] Goal position: {goal}, Robot position: ({x:.2f}, {y:.2f}), Distance: {distance:.2f}") # debug
190+
191+
# 거리 기반 cost (가까울수록 높음)
192+
distance_cost = 1.0 / (distance + 1e-6)
193+
194+
# 각도 차이 계산 함수
195+
def angle_diff(a, b):
196+
diff = (a - b + np.pi) % (2 * np.pi) - np.pi
197+
return diff
198+
199+
# 방향 기반 cost
172200
goal_angle = np.arctan2(dy, dx)
173-
heading_error = goal_angle - trajectory[-1, 2]
174-
heading_error = np.abs(heading_error) % (2 * np.pi)
175-
heading_cost = np.pi - heading_error
176-
# Combined cost: distance + heading (both should be minimized, so we use 1/cost format)
177-
return heading_cost / np.pi
201+
heading_error = abs(angle_diff(goal_angle, theta))
202+
heading_cost = (np.pi - heading_error) / np.pi # 1에 가까울수록 방향이 정확함
203+
204+
# print(f"[DEBUG] Goal cost - Heading: {heading_cost:.4f}, Distance: {distance_cost:.4f}") # debug
205+
206+
# 혼합 cost
207+
total_cost = alpha * heading_cost + beta * distance_cost
208+
return total_cost
209+
210+
178211

179212
# def _calc_obstacle_cost(self, trajectory, obstacles):
180213
# """Obstacle cost - avoids obstacles (optimized for ROSbot2)"""
@@ -229,8 +262,13 @@ def _calc_obstacle_cost(self, trajectory, obstacles):
229262
if len(distances) > 0:
230263
min_dist = np.min(distances)
231264
if min_dist <= safety_radius:
265+
#print(f"[WARNING] 장애물이 매우 가까움! 거리: {min_dist:.2f} m (safety_radius={safety_radius:.2f})")
232266
return 0.0
233267

268+
elif min_dist <= safety_radius + 0.2:
269+
#print(f"[INFO] 장애물 접근 감지: 거리 {min_dist:.2f} m")
270+
return max(min_dist / (safety_radius + 0.2), 0.01)
271+
234272
elif min_dist < min_distance:
235273
min_distance = min_dist
236274

controllers/On_Simulation/DWA/dwa_config.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@ def __init__(self):
88
# Motion parameters based on ROSbot2 capabilities
99
self.dt = 0.032 # [s] Time tick for motion prediction (32ms - Webots timestep)
1010
self.max_accel = 1.0 # [m/s²] Maximum acceleration
11-
self.max_speed = 1.0 # [m/s] Maximum linear velocity (ROSbot2 spec)
11+
self.max_speed = 5.0 # [m/s] Maximum linear velocity (ROSbot2 spec)
1212
self.min_speed = 0.3 # [m/s] Minimum speed (can stop completely)
1313
self.max_yaw_rate = 7.33 # [rad/s] Maximum angular velocity (ROSbot2 spec)
14-
self.max_delta_yaw_rate = 6.0 # [rad/s²] Maximum angular acceleration
14+
self.max_delta_yaw_rate = 10.0 # [rad/s²] Maximum angular acceleration
1515

1616
# Sampling resolutions - optimized for ROSbot2
1717
self.v_resolution = 0.1 # [m/s] Linear velocity sampling resolution
18-
self.predict_time = 3 # [s] Prediction horizon (reduced for faster computation)
18+
self.predict_time = 2 # [s] Prediction horizon (reduced for faster computation)
1919
self.yaw_rate_resolution = 0.1 # [rad/s] Angular velocity sampling resolution
2020

2121
# Robot stuck prevention
2222
self.robot_stuck_flag_cons = 0.01 # Threshold for stuck detection
2323

2424
# Safety margins
25-
self.safety_margin = 0.3 # [m] Additional safety margin around robot
25+
self.safety_margin = 0.35 # [m] Additional safety margin around robot
2626
self.collision_radius = 0.140
2727

2828

0 commit comments

Comments
 (0)