Skip to content

Commit

Permalink
Move to new learning loop project and update detector (#181)
Browse files Browse the repository at this point in the history
We will move the plant detection to a new learning loop project. These
are the needed changes on the field_friend side
  • Loading branch information
pascalzauberzeug authored Sep 24, 2024
1 parent 24ce27e commit b9af332
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 36 deletions.
11 changes: 4 additions & 7 deletions docker-compose.jetson.orin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,21 @@ services:
privileged: true

detector:
image: "zauberzeug/yolov5-detector:0.1.2-nlv0.10.10-35.4.1"
image: "zauberzeug/yolov5-detector:0.1.3-nlv0.10.12-35.4.1"
restart: always
ports:
- "8004:80"
hostname: ${ROBOT_ID}
environment:
- HOST=learning-loop.ai
- NVIDIA_VISIBLE_DEVICES=all
# - ORGANIZATION=zauberzeug
# - PROJECT=coins
- ORGANIZATION=zuckerruebe
- PROJECT=uckerbots
- ORGANIZATION=feldfreund
- PROJECT=plants
volumes:
# - ~/data_coins:/data
- ~/data_plants:/data

monitoring:
image: "zauberzeug/yolov5-detector:0.1.2-nlv0.10.10-35.4.1"
image: "zauberzeug/yolov5-detector:0.1.3-nlv0.10.12-35.4.1"
restart: always
ports:
- "8005:80"
Expand Down
2 changes: 1 addition & 1 deletion field_friend/automations/implements/weeding_implement.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, name: str, system: 'System', persistence_key: str = 'weeding
rosys.persistence.PersistentModule.__init__(self,
persistence_key=f'field_friend.automations.implements.{persistence_key}')

self.relevant_weeds = system.small_weed_category_names + system.big_weed_category_names
self.relevant_weeds = system.plant_locator.weed_category_names
self.log = logging.getLogger('field_friend.weeding')
self.system = system
self.kpi_provider = system.kpi_provider
Expand Down
2 changes: 1 addition & 1 deletion field_friend/automations/implements/weeding_screw.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class WeedingScrew(WeedingImplement):

def __init__(self, system: 'System') -> None:
super().__init__('Weed Screw', system, 'weeding_screw')
self.relevant_weeds = system.small_weed_category_names + system.big_weed_category_names
self.relevant_weeds = system.plant_locator.weed_category_names
self.log.info(f'Using relevant weeds: {self.relevant_weeds}')
self.weed_screw_depth: float = 0.13
self.max_crop_distance: float = 0.08
Expand Down
5 changes: 3 additions & 2 deletions field_friend/automations/plant_locator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@

from .plant import Plant

WEED_CATEGORY_NAME = ['coin', 'weed', 'big_weed', 'thistle', 'orache', 'weedy_area', ]
CROP_CATEGORY_NAME = ['coin_with_hole', 'crop', 'sugar_beet', 'onion', 'garlic', ]
WEED_CATEGORY_NAME = ['coin', 'weed', 'big_weed', 'weedy_area', ]
CROP_CATEGORY_NAME = ['coin_with_hole', 'borrietsch', 'estragon', 'feldsalat', 'garlic', 'jasione', 'kohlrabi', 'liebstoeckel', 'maize', 'minze', 'onion',
'oregano_majoran', 'pastinake', 'petersilie', 'pimpinelle', 'red_beet', 'salatkopf', 'schnittlauch', 'sugar_beet', 'thymian_bohnenkraut', 'zitronenmelisse', ]
MINIMUM_CROP_CONFIDENCE = 0.3
MINIMUM_WEED_CONFIDENCE = 0.3

Expand Down
12 changes: 7 additions & 5 deletions field_friend/interface/components/plant_object.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import logging
from typing import TYPE_CHECKING

import rosys
from nicegui.elements.scene_objects import Group, Sphere

from ...automations import PlantProvider
if TYPE_CHECKING:
from system import System


class plant_objects(Group):

def __init__(self, plant_provider: PlantProvider, weed_category_names: list[str]) -> None:
def __init__(self, system: 'System') -> None:
super().__init__()

self.plant_provider = plant_provider
self.weed_category_names = weed_category_names
self.plant_provider = system.plant_provider
self.plant_locator = system.plant_locator
self.log = logging.getLogger('field_friend.plant_objects')
self.update()
self.plant_provider.PLANTS_CHANGED.register_ui(self.update)
Expand All @@ -29,7 +31,7 @@ def update(self) -> None:
obj.delete()
for id, plant in in_world.items():
if id not in rendered:
if plant.type in self.weed_category_names:
if plant.type in self.plant_locator.weed_category_names:
Sphere(0.02).with_name(f'plant_{plant.type}:{id}') \
.material('#ef1208') \
.move(plant.position.x, plant.position.y, 0.02)
Expand Down
3 changes: 1 addition & 2 deletions field_friend/interface/components/robot_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ def toggle_lock():
with ui.scene(200, 200, on_click=self.handle_click, grid=False).classes('w-full') as self.scene:
field_friend_object(self.system.odometer, self.system.camera_provider, self.system.field_friend)
rosys.driving.driver_object(self.system.driver)
plant_objects(self.system.plant_provider,
self.system.big_weed_category_names + self.system.small_weed_category_names)
plant_objects(self.system)
visualizer_object(self.system)
field_object(self.system.field_provider, self.system.field_navigation.field)
self.scene.move_camera(-0.5, -1, 2)
Expand Down
10 changes: 0 additions & 10 deletions field_friend/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,7 @@ def watch_robot() -> None:
self.kpi_provider.increment_on_rising_edge('low_battery', self.field_friend.bms.is_below_percent(10.0))

self.puncher = Puncher(self.field_friend, self.driver, self.kpi_provider)
self.big_weed_category_names = ['big_weed', 'thistle', 'orache', 'kamille', ]
self.small_weed_category_names = ['coin', 'weed',]
self.crop_category_names = [
'coin_with_hole', 'sugar_beet', 'onion', 'garlic', 'maize', 'liebstoekel',
'red_beet', 'kohlrabi', 'schnittlauch', 'petersilie', 'bohnenkraut', 'sauerampfer',
'oregano', 'pimpinelle', 'borrietsch', 'estragon', 'zitronenmelisse', 'pfefferminze',
'marokanische_minze', 'thymian',
]
self.plant_locator = PlantLocator(self)
self.plant_locator.weed_category_names = self.big_weed_category_names + self.small_weed_category_names
self.plant_locator.crop_category_names = self.crop_category_names

rosys.on_repeat(watch_robot, 1.0)

Expand Down
16 changes: 8 additions & 8 deletions tests/test_weeding.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
async def test_working_with_weeding_screw(system: System, detector: rosys.vision.DetectorSimulation):
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='maize',
position=rosys.geometry.Point3d(x=0.2, y=0.0, z=0)))
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='thistle',
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='big_weed',
position=rosys.geometry.Point3d(x=0.2, y=0.05, z=0)))
system.current_implement = system.implements['Weed Screw']
system.current_navigation = system.straight_line_navigation
Expand All @@ -22,7 +22,7 @@ async def test_working_with_weeding_screw(system: System, detector: rosys.vision
async def test_keep_crops_safe(system: System, detector: rosys.vision.DetectorSimulation):
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='maize',
position=rosys.geometry.Point3d(x=0.2, y=0.0, z=0)))
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='thistle',
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='big_weed',
position=rosys.geometry.Point3d(x=0.2, y=system.field_friend.DRILL_RADIUS-0.01, z=0)))
system.current_implement = system.implements['Weed Screw']
system.current_navigation = system.straight_line_navigation
Expand All @@ -36,7 +36,7 @@ async def test_keep_crops_safe(system: System, detector: rosys.vision.DetectorSi
async def test_weeding_screw_only_targets_big_weed(system: System, detector: rosys.vision.DetectorSimulation):
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='weed',
position=rosys.geometry.Point3d(x=0.2, y=0.0, z=0)))
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='thistle',
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='big_weed',
position=rosys.geometry.Point3d(x=0.15, y=0, z=0)))
system.current_implement = system.implements['Weed Screw']
system.current_navigation = system.straight_line_navigation
Expand All @@ -47,9 +47,9 @@ async def test_weeding_screw_only_targets_big_weed(system: System, detector: ros


async def test_weeding_screw_does_not_skip_close_weed(system: System, detector: rosys.vision.DetectorSimulation):
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='thistle',
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='big_weed',
position=rosys.geometry.Point3d(x=0.2, y=0, z=0)))
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='thistle',
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='big_weed',
position=rosys.geometry.Point3d(x=0.2+system.field_friend.DRILL_RADIUS-0.01, y=0.05, z=0)))
system.current_implement = system.implements['Weed Screw']
system.current_navigation = system.straight_line_navigation
Expand All @@ -61,9 +61,9 @@ async def test_weeding_screw_does_not_skip_close_weed(system: System, detector:
async def test_weeding_screw_focus_on_weed_close_to_crop(system: System, detector: rosys.vision.DetectorSimulation):
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='maize',
position=rosys.geometry.Point3d(x=0.2, y=0.0, z=0)))
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='thistle',
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='big_weed',
position=rosys.geometry.Point3d(x=0.1, y=0, z=0)))
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='thistle',
detector.simulated_objects.append(rosys.vision.SimulatedObject(category_name='big_weed',
position=rosys.geometry.Point3d(x=0.16, y=0, z=0)))
system.current_implement = system.implements['Weed Screw']
system.current_navigation = system.straight_line_navigation
Expand All @@ -73,7 +73,7 @@ async def test_weeding_screw_focus_on_weed_close_to_crop(system: System, detecto
system.automator.start()
await forward(40)
assert len(detector.simulated_objects) == 2
assert detector.simulated_objects[1].category_name == 'thistle'
assert detector.simulated_objects[1].category_name == 'big_weed'
assert detector.simulated_objects[1].position.x == 0.1


Expand Down

0 comments on commit b9af332

Please sign in to comment.