Skip to content

Commit

Permalink
add time tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
Johannes-Thiel committed Oct 7, 2024
1 parent c7ca109 commit 6ebe7a4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
26 changes: 25 additions & 1 deletion field_friend/automations/implements/recorder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Optional

import rosys

Expand All @@ -15,15 +15,39 @@ class Recorder(Implement):
def __init__(self, system: 'System') -> None:
super().__init__('Recorder')
self.system = system
self.kpi_provider = system.kpi_provider
self.state: str = 'idle'
self.start_time: Optional[float] = None
rosys.on_repeat(self._update_time_and_distance, 0.1)

async def activate(self):
self.system.plant_provider.clear()
await self.system.field_friend.flashlight.turn_on()
await rosys.sleep(3) # NOTE: we wait for the camera to adjust
self.system.plant_locator.resume()
await super().activate()

async def prepare(self) -> bool:
self.state = 'running'
return True

async def finish(self) -> None:
self.state = 'idle'
await super().finish()


async def deactivate(self):
self.system.plant_locator.pause()
await self.system.field_friend.flashlight.turn_off()
await super().deactivate()

def _update_time_and_distance(self):
# TODO move this to base class?
if self.state == 'idle':
return
if self.start_time is None:
self.start_time = rosys.time()
passed_time = rosys.time() - self.start_time
if passed_time > 1:
self.kpi_provider.increment_all_time_kpi('time')
self.start_time = rosys.time()
2 changes: 2 additions & 0 deletions field_friend/automations/implements/weeding_implement.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ async def finish(self) -> None:
self.system.plant_locator.pause()
await self.system.field_friend.stop()
await self.system.timelapse_recorder.compress_video()
self.state = 'idle'
await super().finish()

async def activate(self):
Expand Down Expand Up @@ -206,6 +207,7 @@ def _update_time_and_distance(self):
passed_time = rosys.time() - self.start_time
if passed_time > 1:
self.kpi_provider.increment_weeding_kpi('time')
self.kpi_provider.increment_all_time_kpi('time')
self.start_time = rosys.time()

def settings_ui(self):
Expand Down
14 changes: 14 additions & 0 deletions field_friend/automations/kpi_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def __init__(self, plant_provider: PlantProvider) -> None:
self.WEEDING_KPIS_UPDATED = rosys.event.Event()
"""one of the KPIs of the running weeding automation has been updated."""

self.all_time_kpis: KPIs = KPIs()

self.current_mowing_kpis: Mowing_KPIs = Mowing_KPIs()
self.MOWING_KPIS_UPDATED = rosys.event.Event()
"""one of the KPIs of the running mowing automation has been updated."""
Expand All @@ -59,19 +61,31 @@ def backup(self) -> dict:
logger_backup = super().backup()
return {'current_weeding_kpis': rosys.persistence.to_dict(self.current_weeding_kpis),
'current_mowing_kpis': rosys.persistence.to_dict(self.current_mowing_kpis),
'all_time_kpis': rosys.persistence.to_dict(self.all_time_kpis),
'days': logger_backup['days'],
'months': logger_backup['months']}

def restore(self, data: dict[str, Any]) -> None:
super().restore(data)
rosys.persistence.replace_dataclass(self.current_weeding_kpis, data.get('current_weeding_kpis', Weeding_KPIs()))
rosys.persistence.replace_dataclass(self.current_mowing_kpis, data.get('current_mowing_kpis', Mowing_KPIs()))
rosys.persistence.replace_dataclass(self.all_time_kpis, data.get('all_time_kpis', KPIs()))

def invalidate(self) -> None:
self.request_backup()
self.WEEDING_KPIS_UPDATED.emit()
self.MOWING_KPIS_UPDATED.emit()

def increment_all_time_kpi(self, indicator: str) -> None:
self.increment(indicator)
if getattr(self.all_time_kpis, indicator) is None:
new_value = 1
else:
new_value = getattr(self.all_time_kpis, indicator)+1
setattr(self.all_time_kpis, indicator, new_value)
self.invalidate()
return

def increment_weeding_kpi(self, indicator: str) -> None:
self.increment(indicator)
if getattr(self.current_weeding_kpis, indicator) is None:
Expand Down
18 changes: 14 additions & 4 deletions field_friend/interface/components/status_drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,16 @@ def status_drawer(system: 'System', robot: FieldFriend, gnss: Gnss, odometer: ro
with ui.column().bind_visibility_from(system.automator, 'is_running'):
with ui.row().classes('place-items-center'):
ui.markdown('**Current Field:**').style('color: #6E93D6')
current_field_label = ui.label()
with ui.row().classes('place-items-center'):
ui.markdown('**Time on Field:**').style('color: #6E93D6')
kpi_fieldtime_label = ui.label()
with ui.row().classes('place-items-center'):
ui.markdown('**Distance:**').style('color: #6E93D6')
kpi_distance_label = ui.label()
current_field_label = ui.label()
with ui.row().classes('place-items-center'):
ui.markdown('**Time in Automation:**').style('color: #6E93D6')
kpi_time_in_automation = ui.label()
with ui.row().classes('place-items-center'):
ui.markdown('**Current Row:**').style('color: #6E93D6')
current_row_label = ui.label()
Expand All @@ -123,8 +126,13 @@ def status_drawer(system: 'System', robot: FieldFriend, gnss: Gnss, odometer: ro
ui.markdown('**Punches:**').style('color: #6E93D6')
kpi_punches_label = ui.label()

with ui.row().classes('place-items-center').bind_visibility_from(system.automator, 'is_running', backward=lambda x: not x):
ui.markdown('**No automation running**').style('color: #6E93D6')
with ui.column().classes('place-items-center').bind_visibility_from(system.automator, 'is_running', backward=lambda x: not x):
with ui.row().classes('place-items-center'):
ui.markdown('**No automation running**').style('color: #6E93D6')
with ui.row().classes('place-items-center'):
ui.markdown('**Time in Automation**').style('color: #6E93D6')
kpi_time_in_automation_off = ui.label()

ui.markdown('**Positioning**').style('color: #6E93D6').classes('w-full text-center')
ui.separator()

Expand Down Expand Up @@ -224,6 +232,9 @@ def update_status() -> None:
if automator.is_running:
kpi_fieldtime_label.text = f'{system.kpi_provider.current_weeding_kpis.time}s'
kpi_distance_label.text = f'{system.kpi_provider.current_weeding_kpis.distance}m'
kpi_time_in_automation.text = f'{system.kpi_provider.all_time_kpis.time}s'
else:
kpi_time_in_automation_off.text = f'{system.kpi_provider.all_time_kpis.time}s'

# TODO reimplement with navigation and tools
# current_automation = next(key for key, value in system.tools.items()
Expand All @@ -243,6 +254,5 @@ def update_status() -> None:
heading_label.text = f'{system.gnss.current.heading:.2f}° {direction_flag}' if system.gnss.current is not None and system.gnss.current.heading is not None else 'No heading'
rtk_fix_label.text = f'gps_qual: {system.gnss.current.gps_qual}, mode: {system.gnss.current.mode}' if system.gnss.current is not None else 'No fix'
odometry_label.text = str(odometer.prediction)

ui.timer(rosys.config.ui_update_interval, update_status)
return status_drawer

0 comments on commit 6ebe7a4

Please sign in to comment.