Compare commits

..

13 Commits

Author SHA1 Message Date
3b49638afa Correct pothole deletion function
All checks were successful
Component testing / Hub testing (push) Successful in 26s
Component testing / Store testing (push) Successful in 26s
Component testing / Integration smoke testing (push) Successful in 2m33s
2026-03-25 19:52:54 +01:00
366488a8df Use lat lon validation 2026-03-25 19:52:33 +01:00
7355d64971 Add lat lon to pothole mapper 2026-03-25 19:51:58 +01:00
fe4ec12428 Add type hints 2026-03-25 19:51:10 +01:00
805b2658d4 [P] Add bump remove function
All checks were successful
Component testing / Hub testing (push) Successful in 28s
Component testing / Store testing (push) Successful in 32s
Component testing / Integration smoke testing (push) Successful in 2m43s
2026-03-25 19:05:16 +01:00
77d6968297 [P] Fix map lat, lon confusion
All checks were successful
Component testing / Hub testing (push) Successful in 23s
Component testing / Store testing (push) Successful in 18s
Component testing / Integration smoke testing (push) Successful in 2m22s
2026-03-25 14:57:38 +02:00
0c2392dc0b Merge remote-tracking branch 'github/dev' into dev
All checks were successful
Component testing / Hub testing (push) Successful in 20s
Component testing / Store testing (push) Successful in 22s
Component testing / Integration smoke testing (push) Successful in 2m18s
2026-03-25 13:12:18 +02:00
VladiusVostokus
65f767d38e Merge pull request #29 from Rhinemann/lab4/yushchenko-SCRUM-81-DataProcessing-implementation
[L4] SCRUM-81: implementation data processing function
2026-03-25 11:11:31 +00:00
0695e3d092 [P] Use state machine approach to determine road condition 2026-03-25 12:16:34 +02:00
AndriiJushchenko
d6e094e6c0 fix: delay logic in DP 2026-03-25 12:16:34 +02:00
AndriiJushchenko
2167eb2960 DP implementation + delay 2026-03-25 12:16:34 +02:00
VladiusVostokus
38374a6723 Merge pull request #28 from Rhinemann/lab4/shmuliar-FIX-01-wrong-acceleration-data-types
[P] Fix acceleration data types
2026-03-25 10:14:10 +00:00
c08612f71a [P] Fix acceleration data types 2026-03-25 10:10:29 +02:00
8 changed files with 75 additions and 36 deletions

View File

@@ -72,8 +72,8 @@ class Datasource:
) )
new_points = [ new_points = [
( (
processed_agent_data.latitude,
processed_agent_data.longitude, processed_agent_data.longitude,
processed_agent_data.latitude,
processed_agent_data.road_state, processed_agent_data.road_state,
processed_agent_data.user_id processed_agent_data.user_id
) )

View File

@@ -2,6 +2,6 @@ from dataclasses import dataclass
@dataclass @dataclass
class Accelerometer: class Accelerometer:
x: int x: float
y: int y: float
z: int z: float

View File

@@ -14,18 +14,31 @@ line_layer_colors = [
[1, 0, 1, 1], [1, 0, 1, 1],
] ]
def get_lat_lon(point: dict[str, float] | list[float] | tuple[float, float]) -> tuple[float, float] | None:
if isinstance(point, dict):
lat = point.get("lat")
lon = point.get("lon")
else:
lat, lon = point
if lat is None or lon is None:
return None
return lat, lon
class MapViewApp(App): class MapViewApp(App):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.mapview = None self.mapview: MapView | None = None
self.datasource = Datasource(user_id=1) self.datasource = Datasource(user_id=1)
self.line_layers = dict() self.line_layers = dict()
self.car_markers = dict() self.car_markers = dict()
# додати необхідні змінні # додати необхідні змінні
self.bump_markers = [] self.bump_markers: list[MapMarker] = []
self.pothole_markers = [] self.pothole_markers: list[MapMarker] = []
def on_start(self): def on_start(self):
""" """
@@ -87,15 +100,17 @@ class MapViewApp(App):
self.car_markers[user_id].lat = lat self.car_markers[user_id].lat = lat
self.car_markers[user_id].lon = lon self.car_markers[user_id].lon = lon
if user_id == 1:
self.mapview.center_on(lat, lon) self.mapview.center_on(lat, lon)
def set_pothole_marker(self, point): def map_lat_lon_to_pothole(self, lat: float, lon: float) -> MapMarker | None:
if isinstance(point, dict): click_tolerance = self.mapview.zoom * 10
lat = point.get("lat") flt = filter(lambda marker: abs(lat - marker.lat) + abs(lon - marker.lon) < click_tolerance,
lon = point.get("lon") self.pothole_markers)
else: return next(flt)
lat, lon = point
def set_pothole_marker(self, point):
lat, lon = get_lat_lon(point)
if lat is None or lon is None: if lat is None or lon is None:
return return
@@ -109,12 +124,7 @@ class MapViewApp(App):
self.pothole_markers.append(marker) self.pothole_markers.append(marker)
def set_bump_marker(self, point): def set_bump_marker(self, point):
if isinstance(point, dict): lat, lon = get_lat_lon(point)
lat = point.get("lat")
lon = point.get("lon")
else:
lat, lon = point
if lat is None or lon is None: if lat is None or lon is None:
return return
@@ -127,6 +137,16 @@ class MapViewApp(App):
self.mapview.add_marker(marker) self.mapview.add_marker(marker)
self.bump_markers.append(marker) self.bump_markers.append(marker)
def delete_pothole_marker(self, point):
lat, lon = get_lat_lon(point)
if lat is None or lon is None:
return
pothole = self.map_lat_lon_to_pothole(lat, lon)
if pothole:
self.mapview.remove_marker(pothole)
self.pothole_markers.pop(self.pothole_markers.index(pothole))
def build(self): def build(self):
""" """

View File

@@ -3,6 +3,6 @@ from dataclasses import dataclass
@dataclass @dataclass
class Accelerometer: class Accelerometer:
x: int x: float
y: int y: float
z: int z: float

View File

@@ -15,6 +15,7 @@ class FileDatasource:
def __init__( def __init__(
self, self,
acc_divisor: float,
accelerometer_filename: str, accelerometer_filename: str,
gps_filename: str, gps_filename: str,
park_filename: str, park_filename: str,
@@ -34,6 +35,8 @@ class FileDatasource:
self._started = False self._started = False
self.acc_divisor = acc_divisor
def startReading(self, *args, **kwargs): def startReading(self, *args, **kwargs):
"""Must be called before read()""" """Must be called before read()"""
if self._started: if self._started:
@@ -160,15 +163,14 @@ class FileDatasource:
return row return row
@staticmethod def _parse_acc(self, row: List[str]) -> Accelerometer:
def _parse_acc(row: List[str]) -> Accelerometer:
if len(row) < 3: if len(row) < 3:
raise ValueError(f"Accelerometer row must have 3 values (x,y,z). Got: {row}") raise ValueError(f"Accelerometer row must have 3 values (x,y,z). Got: {row}")
try: try:
x = int(row[0]) x = int(row[0]) / self.acc_divisor
y = int(row[1]) y = int(row[1]) / self.acc_divisor
z = int(row[2]) z = int(row[2]) / self.acc_divisor
except ValueError as e: except ValueError as e:
raise ValueError(f"Invalid accelerometer values (expected integers): {row}") from e raise ValueError(f"Invalid accelerometer values (expected integers): {row}") from e

View File

@@ -39,7 +39,7 @@ def run():
# Prepare mqtt client # Prepare mqtt client
client = connect_mqtt(config.MQTT_BROKER_HOST, config.MQTT_BROKER_PORT) client = connect_mqtt(config.MQTT_BROKER_HOST, config.MQTT_BROKER_PORT)
# Prepare datasource # Prepare datasource
datasource = FileDatasource("data/accelerometer.csv", "data/gps.csv", "data/parking.csv") datasource = FileDatasource(16384.0, "data/accelerometer.csv", "data/gps.csv", "data/parking.csv")
# Infinity publish data # Infinity publish data
publish(client, config.MQTT_TOPIC, datasource) publish(client, config.MQTT_TOPIC, datasource)

View File

@@ -2,6 +2,6 @@ from marshmallow import Schema, fields
class AccelerometerSchema(Schema): class AccelerometerSchema(Schema):
x = fields.Int() x = fields.Float()
y = fields.Int() y = fields.Float()
z = fields.Int() z = fields.Float()

View File

@@ -1,6 +1,7 @@
from app.entities.agent_data import AgentData from app.entities.agent_data import AgentData
from app.entities.processed_agent_data import ProcessedAgentData from app.entities.processed_agent_data import ProcessedAgentData
_last_detection_state = {}
def process_agent_data( def process_agent_data(
agent_data: AgentData, agent_data: AgentData,
@@ -12,8 +13,24 @@ def process_agent_data(
Returns: Returns:
processed_data_batch (ProcessedAgentData): Processed data containing the classified state of the road surface and agent data. processed_data_batch (ProcessedAgentData): Processed data containing the classified state of the road surface and agent data.
""" """
# Implement it user_id = agent_data.user_id
road_state = "normal"
last_detection_state = _last_detection_state.get(user_id, False)
if (agent_data.accelerometer.z < 0.6):
road_state = "pothole"
elif (agent_data.accelerometer.z > 1.2):
road_state = "bump"
detection_happened = road_state != "normal"
if not (not last_detection_state and detection_happened):
road_state = "normal"
_last_detection_state[user_id] = detection_happened
return ProcessedAgentData( return ProcessedAgentData(
road_state="normal", road_state=road_state,
agent_data=agent_data agent_data=agent_data
) )