11. Testing in GAMA GUI
By Killian Trouillet
From Headless to GUIβ
During training, we used GAMA in headless mode for speed. Now that the model is trained, we switch to the GAMA GUI to watch the agent in action.
Key Differenceβ
| Mode | Port | Speed | Display | Use |
|---|---|---|---|---|
| Headless | 1001 | Fast (no rendering) | None | Training |
| GUI | 1000 | Slow (renders display) | Yes | Testing / Visualization |
Starting GAMA GUIβ
- Open GAMA normally (double-click the application)
- The GUI server runs on port 1000 by default β no extra setup needed
The Test Scriptβ
Loading the Trained Modelβ
from stable_baselines3 import PPO
model = PPO.load("saved_models/ppo_forager")
This loads the neural network weights saved during training.
Connecting to GUIβ
The only change from training: the port number.
env = None
for attempt in range(5):
try:
env = gym.make(
"gama_gymnasium_env/GamaEnv-v0",
gaml_experiment_path="path/to/forager_gym.gaml",
gaml_experiment_name="gym_env",
gama_ip_address="localhost",
gama_port=1000,
)
break
except Exception as e:
print(f"GAMA GUI not ready. Retrying in 5s...")
time.sleep(5)
if env is None:
raise RuntimeError("Failed to connect to GAMA GUI after several attempts.")
Deterministic Evaluationβ
action, _ = model.predict(obs, deterministic=True)
During training, the policy adds noise to explore new strategies. During testing, we set deterministic=True to use the pure learned policy β no randomness, just the best action the network has learned.
Slow Motionβ
time.sleep(0.1) # 100ms delay between steps
We add a small delay between steps so the movement is visible in the GAMA display.
Complete Test Scriptβ
Note: The GAML model is unchanged from Step 9. See the Complete Model section there for the full
forager_gym.gaml.
"""
Smart Forager - Test Script (GUI Visualization)
Author: Killian Trouillet
Usage:
1. Open GAMA GUI (default port 1000)
2. Run this script: python test_forager.py
"""
import asyncio
from pathlib import Path
import gymnasium as gym
import gama_gymnasium
from stable_baselines3 import PPO
import numpy as np
import time
GAML_FILE = str(Path(__file__).parent / "forager_gym.gaml")
EXPERIMENT_NAME = "gym_env"
GAMA_PORT = 1000
MODEL_PATH = str(Path(__file__).parent / "saved_models" / "ppo_forager")
NUM_EPISODES = 5
STEP_DELAY = 0.1
async def test():
print("=" * 50)
print(" Smart Forager - PPO Test (GUI)")
print("=" * 50)
print(f"Loading model from: {MODEL_PATH}")
model = PPO.load(MODEL_PATH)
print("Model loaded successfully!")
# ---- Create the environment (connected to GAMA GUI) ----
# We use a retry loop because GAMA GUI takes time to initialize the simulation
env = None
for attempt in range(5):
try:
print(f"Connecting to GAMA GUI (attempt {attempt + 1}/5)...")
env = gym.make(
"gama_gymnasium_env/GamaEnv-v0",
gaml_experiment_path=GAML_FILE,
gaml_experiment_name=EXPERIMENT_NAME,
gama_ip_address="localhost",
gama_port=GAMA_PORT,
)
break
except Exception as e:
if "Unable to find" in str(e) or "NOTREADY" in str(e):
print(f"GAMA simulation not ready yet. Waiting 5s...")
time.sleep(5)
else:
raise e
if env is None:
print("Failed to connect to GAMA GUI after several attempts.")
return
print(f"\nRunning {NUM_EPISODES} test episodes...\n")
all_rewards = []
all_steps = []
for episode in range(NUM_EPISODES):
obs, info = env.reset()
time.sleep(1)
total_reward = 0.0
step = 0
done = False
while not done:
action, _ = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
step += 1
done = terminated or truncated
time.sleep(STEP_DELAY)
all_rewards.append(total_reward)
all_steps.append(step)
status = "FOUND FOOD!" if terminated else "TIMEOUT"
print(f" Episode {episode + 1}/{NUM_EPISODES}: "
f"{status} | Steps: {step} | Reward: {total_reward:.1f}")
env.close()
print(f"\n{'=' * 50}")
print(f" Test Results Summary")
print(f"{'=' * 50}")
print(f" Episodes: {NUM_EPISODES}")
print(f" Avg Reward: {np.mean(all_rewards):.1f}")
print(f" Avg Steps: {np.mean(all_steps):.0f}")
print(f" Success Rate: "
f"{sum(1 for r in all_rewards if r > 50) / NUM_EPISODES * 100:.0f}%")
print(f"{'=' * 50}")
if __name__ == "__main__":
asyncio.run(test())
Running the Testβ
cd models/gym
python test_forager.py
Watch the GAMA display β the blue forager should navigate smoothly around obstacles to reach the green food!
Expected Console Outputβ
==================================================
Smart Forager - PPO Test (GUI)
==================================================
Loading model from: saved_models/ppo_forager
Model loaded successfully!
Running 5 test episodes...
Episode 1/5: FOUND FOOD! | Steps: 47 | Reward: 93.2
Episode 2/5: FOUND FOOD! | Steps: 52 | Reward: 91.8
Episode 3/5: FOUND FOOD! | Steps: 45 | Reward: 94.1
Episode 4/5: FOUND FOOD! | Steps: 49 | Reward: 92.5
Episode 5/5: FOUND FOOD! | Steps: 51 | Reward: 91.4
==================================================
Test Results Summary
==================================================
Episodes: 5
Avg Reward: 92.6
Avg Steps: 49
Success Rate: 100%
==================================================
Summaryβ
| Concept | Implementation |
|---|---|
| Continuous world | No grid, free {x, y} movement in 100Γ100 space |
| GAMAβPython bridge | GymAgent species + gama-gymnasium WebSocket |
| Neural network policy | PPO("MlpPolicy", ...) via Stable Baselines3 |
| Headless training | gama-headless.bat -socket 1001 β fast, no GUI |
| GUI testing | PPO.load() + connect to GAMA GUI (port 1000) |
| Action space | Box([-1,-1], [1,1]) β continuous velocity (dx, dy) |
| Observation space | Box([0]Γ13, [1]Γ13) β position + food direction + 8 sensors |
| Reward shaping | Distance delta bonus + food reward + living penalty |
Key GAML Concepts Usedβ
global, species, reflex, action, aspect, experiment, parameter, geometry, rectangle, circle, line, distance_to, towards, intersects, inter, cos, sin, list, map, loop, draw
Key Python Concepts Usedβ
gymnasium, gym.make(), env.reset(), env.step(), PPO, MlpPolicy, model.learn(), model.save(), model.load(), model.predict(), asyncio, BaseCallback
Key Filesβ
| File | Description |
|---|---|
models/gym/forager_gym.gaml | GAMA model with GymAgent bridge |
models/gym/train_forager.py | PPO training script (headless) |
models/gym/test_forager.py | Testing script (GUI visualization) |