GardenRL / examples /example_episode.py
yvesjr's picture
Upload folder using huggingface_hub
317872d verified
Raw
History Blame Contribute Delete
6.49 kB
"""
Example episodes demonstrating GardenRL hydroponic simulation.
This script runs two contrasting episodes:
1. Optimal management - Active pH/EC control leads to healthy 200g+ harvest
2. Neglect - No intervention leads to plant death or poor harvest
Run with: python examples/example_episode.py
"""
import sys
sys.path.insert(0, '/Users/yves/Developer/GardenRL')
from server.GardenRL_environment import GardenrlEnvironment
from models import GardenrlAction
def run_optimal_episode():
"""
Run episode with good management practices.
Expected outcome: 150-250g harvest (1500-2500 reward)
"""
env = GardenrlEnvironment(seed=42) # Reproducible
obs = env.reset()
print("=" * 70)
print("OPTIMAL MANAGEMENT EPISODE")
print("=" * 70)
print(f"Day {obs.day}: pH={obs.ph:.2f}, EC={obs.ec:.2f}, Stage={obs.growth_stage}")
print()
for day in range(30):
# Simple rule-based policy
reasoning = ""
if obs.ph > 6.5:
action = GardenrlAction(
action_type="adjust_ph_down",
ph_adjustment=0.3,
reasoning=f"pH {obs.ph:.2f} too high, risk of nutrient lockout"
)
reasoning = f"↓ Lowering pH (was {obs.ph:.2f})"
elif obs.ph < 5.5:
action = GardenrlAction(
action_type="adjust_ph_up",
ph_adjustment=0.3,
reasoning=f"pH {obs.ph:.2f} too low, calcium uptake impaired"
)
reasoning = f"↑ Raising pH (was {obs.ph:.2f})"
elif obs.ec < 1.2:
action = GardenrlAction(
action_type="add_nutrients",
nutrient_adjustment=0.4,
reasoning=f"EC {obs.ec:.2f} low, plants need more nutrients"
)
reasoning = f"+ Adding nutrients (EC was {obs.ec:.2f})"
elif obs.ec > 2.0:
action = GardenrlAction(
action_type="dilute_nutrients",
nutrient_adjustment=0.3,
reasoning=f"EC {obs.ec:.2f} high, risk of nutrient burn"
)
reasoning = f"βˆ’ Diluting nutrients (EC was {obs.ec:.2f})"
elif day >= 27:
action = GardenrlAction(
action_type="harvest",
reasoning="Day 27, optimal harvest time for Batavia lettuce"
)
reasoning = "βœ‚οΈ Harvesting plant"
else:
action = GardenrlAction(
action_type="maintain",
reasoning="All parameters optimal, maintaining current conditions"
)
reasoning = "βœ“ Maintaining (all optimal)"
obs = env.step(action)
# Print status every few days
if day % 3 == 0 or day >= 27 or obs.warnings:
print(f"Day {obs.day:2d}: pH={obs.ph:4.1f} EC={obs.ec:4.2f} "
f"Temp={obs.water_temp:4.1f}Β°C β”‚ "
f"Leaves={obs.estimated_leaf_count:2d} "
f"Height={obs.plant_height_cm:4.1f}cm β”‚ "
f"{obs.leaf_color:15s} β”‚ {reasoning}")
if obs.warnings:
for warning in obs.warnings:
print(f" ⚠️ {warning}")
if obs.done:
print()
print("=" * 70)
print("🌱 EPISODE COMPLETE!")
print("=" * 70)
print(f"Final Reward: {obs.reward:.1f}")
harvest_weight = obs.reward / 10.0
print(f"Harvest Weight: {harvest_weight:.1f}g")
print(f"Growth Stage: {obs.growth_stage}")
print(f"Leaf Color: {obs.leaf_color}")
print()
if harvest_weight >= 150:
print("βœ… SUCCESS: Healthy harvest! (150g+ is commercial quality)")
elif harvest_weight >= 100:
print("⚠️ ACCEPTABLE: Viable harvest, but suboptimal")
else:
print("❌ POOR: Failed to produce healthy plant")
print()
break
def run_neglect_episode():
"""
Run episode with no management (neglect).
Expected outcome: Plant dies or yields <100g (0-1000 reward)
"""
env = GardenrlEnvironment(seed=42) # Same seed for comparison
obs = env.reset()
print("=" * 70)
print("NEGLECT EPISODE (NO MANAGEMENT)")
print("=" * 70)
print(f"Day {obs.day}: pH={obs.ph:.2f}, EC={obs.ec:.2f}")
print("Strategy: Do nothing, let nature take its course")
print()
for day in range(30):
# Do nothing - just maintain
action = GardenrlAction(
action_type="maintain",
reasoning="Ignoring all warnings (neglect scenario)"
)
obs = env.step(action)
# Print status every 3 days
if day % 3 == 0 or obs.warnings or obs.done:
print(f"Day {obs.day:2d}: pH={obs.ph:4.1f} EC={obs.ec:4.2f} β”‚ "
f"{obs.leaf_color:15s} β”‚ Stage={obs.growth_stage}")
if obs.warnings:
for warning in obs.warnings:
print(f" ⚠️ {warning}")
if obs.done:
print()
print("=" * 70)
if obs.growth_stage == "dead":
print("πŸ’€ PLANT DIED")
else:
print("🌱 EPISODE ENDED")
print("=" * 70)
print(f"Final Reward: {obs.reward:.1f}")
harvest_weight = obs.reward / 10.0
print(f"Harvest Weight: {harvest_weight:.1f}g")
print(f"Growth Stage: {obs.growth_stage}")
print()
if harvest_weight < 100:
print("❌ FAILED: Poor management led to severe crop loss")
print()
break
if __name__ == "__main__":
run_optimal_episode()
print("\n")
run_neglect_episode()
print("\n" + "=" * 70)
print("SUMMARY")
print("=" * 70)
print("This demonstrates the long-horizon planning challenge:")
print("- Optimal management β†’ 150-250g harvest (1500-2500 reward)")
print("- Neglect β†’ Death or <100g harvest (0-1000 reward)")
print()
print("Key mechanics:")
print(" β€’ pH naturally drifts upward β†’ requires active management")
print(" β€’ EC depletes over time β†’ nutrient supplementation needed")
print(" β€’ Poor pH β†’ nutrient lockout β†’ stunted growth β†’ poor harvest")
print(" β€’ Delayed consequences: mistakes on day 5 affect harvest on day 30")
print("=" * 70)