| """ |
| 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) |
| 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): |
| |
| 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) |
|
|
| |
| 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) |
| 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): |
| |
| action = GardenrlAction( |
| action_type="maintain", |
| reasoning="Ignoring all warnings (neglect scenario)" |
| ) |
|
|
| obs = env.step(action) |
|
|
| |
| 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) |
|
|