YashsharmaPhD commited on
Commit
61a9b14
·
verified ·
1 Parent(s): b249855

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -57
app.py CHANGED
@@ -15,31 +15,20 @@ color_index = 0
15
  rgb_colors = ['red', 'green', 'blue']
16
  noise_enabled = True
17
 
18
- # Mode state
19
  mode = "Manual"
20
  auto_running = False
21
- auto_thread = None
22
 
23
- # Generate random obstacles
24
  def generate_obstacles(count=10):
25
- obs = []
26
- for _ in range(count):
27
- obs.append({
28
- "x": random.uniform(-8, 8),
29
- "z": random.uniform(-8, 8),
30
- "radius": random.uniform(0.5, 1.2)
31
- })
32
- return obs
33
 
34
  obstacles = generate_obstacles(10)
35
 
36
- # Toggle sensor noise
37
  def toggle_noise():
38
  global noise_enabled
39
  noise_enabled = not noise_enabled
40
  return "Noise: ON" if noise_enabled else "Noise: OFF"
41
 
42
- # Reset simulation
43
  def reset_sim(count):
44
  global pose, trajectory, obstacles, obstacle_hits, color_index, auto_running
45
  auto_running = False
@@ -50,7 +39,6 @@ def reset_sim(count):
50
  obstacles = generate_obstacles(int(count))
51
  return render_env(), render_slam_map(), None, f"Simulation Reset with {count} obstacles"
52
 
53
- # Check for collision
54
  def check_collision(x, z):
55
  for obs in obstacles:
56
  dist = np.sqrt((obs["x"] - x)**2 + (obs["z"] - z)**2)
@@ -58,7 +46,6 @@ def check_collision(x, z):
58
  return True
59
  return False
60
 
61
- # Move robot
62
  def move_robot(direction):
63
  global pose, trajectory
64
  step = 1
@@ -92,7 +79,6 @@ def move_robot(direction):
92
 
93
  return render_env(), render_slam_map(), None, "Moved " + direction
94
 
95
- # Render robot + LiDAR environment
96
  def render_env():
97
  global obstacle_hits
98
  fig, ax = plt.subplots()
@@ -112,7 +98,6 @@ def render_env():
112
 
113
  ax.plot(pose["x"], pose["z"], 'ro', markersize=8)
114
 
115
- # Simulate lidar scan lines
116
  angles = np.linspace(0, 2*np.pi, 24)
117
  for ang in angles:
118
  for r in np.linspace(0, 3, 30):
@@ -126,7 +111,6 @@ def render_env():
126
  plt.close(fig)
127
  return fig
128
 
129
- # Render SLAM trajectory map
130
  def render_slam_map():
131
  global color_index
132
  fig, ax = plt.subplots()
@@ -136,7 +120,6 @@ def render_slam_map():
136
  ax.plot(x_vals, z_vals, 'bo-', markersize=3)
137
  ax.grid(True)
138
 
139
- # RGB blinking dots at last few obstacle hits
140
  if obstacle_hits:
141
  current_color = rgb_colors[color_index % 3]
142
  for hit in obstacle_hits[-20:]:
@@ -146,26 +129,21 @@ def render_slam_map():
146
  plt.close(fig)
147
  return fig
148
 
149
- # Text input handler
150
  def handle_text_input(direction):
151
  return move_robot(direction.strip().upper())
152
 
153
- # Set mode (manual/automatic)
154
  def set_mode(new_mode):
155
  global mode
156
  mode = new_mode
157
  return f"Mode set to: {mode}"
158
 
159
- # Auto move thread logic
160
- def auto_move_loop(update_outputs):
161
  global auto_running
162
  directions = ["W", "A", "S", "D"]
163
  while auto_running:
164
- valid_dirs = directions.copy()
165
- random.shuffle(valid_dirs)
166
  moved = False
167
-
168
- for dir in valid_dirs:
169
  step = 1
170
  if dir == "W":
171
  new_x, new_z = pose["x"], pose["z"] + step
@@ -177,52 +155,38 @@ def auto_move_loop(update_outputs):
177
  new_x, new_z = pose["x"] + step, pose["z"]
178
 
179
  if not check_collision(new_x, new_z):
180
- env, slam, audio, msg = move_robot(dir)
181
- update_outputs(env, slam, audio, f"[AUTO] {msg}")
182
  moved = True
183
  break
184
-
185
  if not moved:
186
- update_outputs(render_env(), render_slam_map(), "collision.mp3", "[AUTO] No path available!")
187
  auto_running = False
188
- break
189
-
190
  time.sleep(1)
191
 
192
- # Start auto mode
193
- def start_auto(env, slam, audio, status):
194
- global auto_running, auto_thread
195
  if mode != "Automatic":
196
- return env, slam, audio, "Switch to 'Automatic' mode to start."
197
-
198
  if auto_running:
199
- return env, slam, audio, "Auto mode already running."
200
-
201
  auto_running = True
 
 
202
 
203
- def update(env_, slam_, audio_, status_):
204
- env.update(env_)
205
- slam.update(slam_)
206
- audio.update(audio_)
207
- status.update(status_)
208
 
209
- auto_thread = threading.Thread(target=auto_move_loop, args=(lambda e, s, a, t: update(e, s, a, t),))
210
- auto_thread.start()
211
- return env, slam, audio, "Auto movement started."
212
-
213
- # Gradio UI
214
  with gr.Blocks() as demo:
215
- gr.Markdown("## 🤖 SLAM Simulation: Manual & Automatic Robot Navigation")
216
 
217
  obstacle_slider = gr.Slider(1, 20, value=10, step=1, label="Number of Obstacles")
218
 
219
- direction_input = gr.Textbox(label="Type W / A / S / D and press Enter to move", placeholder="e.g., W")
220
  status_text = gr.Textbox(label="Status")
221
  collision_audio = gr.Audio(label="Collision Sound", interactive=False)
222
 
223
  with gr.Row():
224
  with gr.Column():
225
- env_plot = gr.Plot(label="Robot + Sensor View")
226
  with gr.Column():
227
  slam_plot = gr.Plot(label="SLAM Map")
228
 
@@ -235,10 +199,11 @@ with gr.Blocks() as demo:
235
  toggle = gr.Button("🔀 Toggle Noise")
236
 
237
  with gr.Row():
238
- mode_selector = gr.Dropdown(choices=["Manual", "Automatic"], value="Manual", label="Select Mode")
239
- start_auto_btn = gr.Button("▶️ Start Auto Mode")
 
 
240
 
241
- # Button wiring
242
  w.click(fn=move_robot, inputs=gr.State("W"), outputs=[env_plot, slam_plot, collision_audio, status_text])
243
  a.click(fn=move_robot, inputs=gr.State("A"), outputs=[env_plot, slam_plot, collision_audio, status_text])
244
  s.click(fn=move_robot, inputs=gr.State("S"), outputs=[env_plot, slam_plot, collision_audio, status_text])
@@ -248,6 +213,6 @@ with gr.Blocks() as demo:
248
  direction_input.submit(fn=handle_text_input, inputs=direction_input, outputs=[env_plot, slam_plot, collision_audio, status_text])
249
 
250
  mode_selector.change(fn=set_mode, inputs=mode_selector, outputs=status_text)
251
- start_auto_btn.click(fn=start_auto, inputs=[env_plot, slam_plot, collision_audio, status_text], outputs=[env_plot, slam_plot, collision_audio, status_text])
252
 
253
  demo.launch()
 
15
  rgb_colors = ['red', 'green', 'blue']
16
  noise_enabled = True
17
 
 
18
  mode = "Manual"
19
  auto_running = False
20
+ obstacles = []
21
 
 
22
  def generate_obstacles(count=10):
23
+ return [{"x": random.uniform(-8, 8), "z": random.uniform(-8, 8), "radius": random.uniform(0.5, 1.2)} for _ in range(count)]
 
 
 
 
 
 
 
24
 
25
  obstacles = generate_obstacles(10)
26
 
 
27
  def toggle_noise():
28
  global noise_enabled
29
  noise_enabled = not noise_enabled
30
  return "Noise: ON" if noise_enabled else "Noise: OFF"
31
 
 
32
  def reset_sim(count):
33
  global pose, trajectory, obstacles, obstacle_hits, color_index, auto_running
34
  auto_running = False
 
39
  obstacles = generate_obstacles(int(count))
40
  return render_env(), render_slam_map(), None, f"Simulation Reset with {count} obstacles"
41
 
 
42
  def check_collision(x, z):
43
  for obs in obstacles:
44
  dist = np.sqrt((obs["x"] - x)**2 + (obs["z"] - z)**2)
 
46
  return True
47
  return False
48
 
 
49
  def move_robot(direction):
50
  global pose, trajectory
51
  step = 1
 
79
 
80
  return render_env(), render_slam_map(), None, "Moved " + direction
81
 
 
82
  def render_env():
83
  global obstacle_hits
84
  fig, ax = plt.subplots()
 
98
 
99
  ax.plot(pose["x"], pose["z"], 'ro', markersize=8)
100
 
 
101
  angles = np.linspace(0, 2*np.pi, 24)
102
  for ang in angles:
103
  for r in np.linspace(0, 3, 30):
 
111
  plt.close(fig)
112
  return fig
113
 
 
114
  def render_slam_map():
115
  global color_index
116
  fig, ax = plt.subplots()
 
120
  ax.plot(x_vals, z_vals, 'bo-', markersize=3)
121
  ax.grid(True)
122
 
 
123
  if obstacle_hits:
124
  current_color = rgb_colors[color_index % 3]
125
  for hit in obstacle_hits[-20:]:
 
129
  plt.close(fig)
130
  return fig
131
 
 
132
  def handle_text_input(direction):
133
  return move_robot(direction.strip().upper())
134
 
 
135
  def set_mode(new_mode):
136
  global mode
137
  mode = new_mode
138
  return f"Mode set to: {mode}"
139
 
140
+ def auto_move_thread():
 
141
  global auto_running
142
  directions = ["W", "A", "S", "D"]
143
  while auto_running:
144
+ random.shuffle(directions)
 
145
  moved = False
146
+ for dir in directions:
 
147
  step = 1
148
  if dir == "W":
149
  new_x, new_z = pose["x"], pose["z"] + step
 
155
  new_x, new_z = pose["x"] + step, pose["z"]
156
 
157
  if not check_collision(new_x, new_z):
158
+ move_robot(dir)
 
159
  moved = True
160
  break
 
161
  if not moved:
 
162
  auto_running = False
 
 
163
  time.sleep(1)
164
 
165
+ def start_auto():
166
+ global auto_running
 
167
  if mode != "Automatic":
168
+ return "Switch to 'Automatic' mode first."
 
169
  if auto_running:
170
+ return "Auto already running."
 
171
  auto_running = True
172
+ threading.Thread(target=auto_move_thread, daemon=True).start()
173
+ return "▶️ Auto started."
174
 
175
+ def get_state():
176
+ return render_env(), render_slam_map(), None, "Auto Running" if auto_running else "Idle"
 
 
 
177
 
 
 
 
 
 
178
  with gr.Blocks() as demo:
179
+ gr.Markdown("## 🤖 SLAM: Manual + Automatic Robot Navigation")
180
 
181
  obstacle_slider = gr.Slider(1, 20, value=10, step=1, label="Number of Obstacles")
182
 
183
+ direction_input = gr.Textbox(label="Type W / A / S / D", placeholder="W")
184
  status_text = gr.Textbox(label="Status")
185
  collision_audio = gr.Audio(label="Collision Sound", interactive=False)
186
 
187
  with gr.Row():
188
  with gr.Column():
189
+ env_plot = gr.Plot(label="Robot View")
190
  with gr.Column():
191
  slam_plot = gr.Plot(label="SLAM Map")
192
 
 
199
  toggle = gr.Button("🔀 Toggle Noise")
200
 
201
  with gr.Row():
202
+ mode_selector = gr.Dropdown(["Manual", "Automatic"], value="Manual", label="Mode")
203
+ start_auto_btn = gr.Button("▶️ Start Auto")
204
+
205
+ poll = gr.Button("⏱️ Refresh View", visible=False).every(1000, get_state, outputs=[env_plot, slam_plot, collision_audio, status_text])
206
 
 
207
  w.click(fn=move_robot, inputs=gr.State("W"), outputs=[env_plot, slam_plot, collision_audio, status_text])
208
  a.click(fn=move_robot, inputs=gr.State("A"), outputs=[env_plot, slam_plot, collision_audio, status_text])
209
  s.click(fn=move_robot, inputs=gr.State("S"), outputs=[env_plot, slam_plot, collision_audio, status_text])
 
213
  direction_input.submit(fn=handle_text_input, inputs=direction_input, outputs=[env_plot, slam_plot, collision_audio, status_text])
214
 
215
  mode_selector.change(fn=set_mode, inputs=mode_selector, outputs=status_text)
216
+ start_auto_btn.click(fn=start_auto, outputs=status_text)
217
 
218
  demo.launch()