Skip to content

Commit

Permalink
Merge branch 'cluster-estimation-worker-integration-redo' of https://…
Browse files Browse the repository at this point in the history
…github.com/UWARG/computer-vision-python into cluster-estimation-worker-integration-redo
  • Loading branch information
Aleksa-M committed Nov 10, 2024
2 parents 4f0968a + 3f799e0 commit 5001a51
Show file tree
Hide file tree
Showing 32 changed files with 200 additions and 356 deletions.
7 changes: 3 additions & 4 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ geolocation:
camera_orientation_pitch: -1.57079632679
camera_orientation_roll: 0.0

# default values set
cluster_merge:
min_activation_threshold: 0
min_new_points_to_run: 0
cluster_estimation:
min_activation_threshold: 25
min_new_points_to_run: 5
random_state: 0
8 changes: 4 additions & 4 deletions documentation/main_multiprocess_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
from documentation.multiprocess_example.add_random import add_random_worker
from documentation.multiprocess_example.concatenator import concatenator_worker
from documentation.multiprocess_example.countup import countup_worker
from modules.common.logger.modules import logger
from modules.common.logger.modules import logger_setup_main
from modules.common.logger.read_yaml.modules import read_yaml
from modules.common.modules.logger import logger
from modules.common.modules.logger import logger_main_setup
from modules.common.modules.read_yaml import read_yaml
from utilities.workers import queue_proxy_wrapper
from utilities.workers import worker_controller
from utilities.workers import worker_manager
Expand Down Expand Up @@ -44,7 +44,7 @@ def main() -> int:
assert config is not None

# Setup main logger
result, main_logger, _ = logger_setup_main.setup_main_logger(config)
result, main_logger, _ = logger_main_setup.setup_main_logger(config)
if not result:
print("ERROR: Failed to create main logger")
return -1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import time
import random

from modules.common.logger.modules import logger
from modules.common.modules.logger import logger
from .. import intermediate_struct


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os
import pathlib

from modules.common.logger.modules import logger
from modules.common.modules.logger import logger
from utilities.workers import queue_proxy_wrapper
from utilities.workers import worker_controller
from . import add_random
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import time

from modules.common.logger.modules import logger
from modules.common.modules.logger import logger
from .. import intermediate_struct


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os
import pathlib

from modules.common.logger.modules import logger
from modules.common.modules.logger import logger
from utilities.workers import queue_proxy_wrapper
from utilities.workers import worker_controller
from . import concatenator
Expand Down
2 changes: 1 addition & 1 deletion documentation/multiprocess_example/countup/countup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import time

from modules.common.logger.modules import logger
from modules.common.modules.logger import logger


class Countup:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os
import pathlib

from modules.common.logger.modules import logger
from modules.common.modules.logger import logger
from utilities.workers import queue_proxy_wrapper
from utilities.workers import worker_controller
from . import countup
Expand Down
17 changes: 12 additions & 5 deletions main_2024.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def main() -> int:
assert config_logger is not None

# Setup main logger
result, main_logger, logging_path = logger_setup_main.setup_main_logger(config_logger)
result, main_logger, logging_path = logger_main_setup.setup_main_logger(config_logger)
if not result:
print("ERROR: Failed to create main logger")
return -1
Expand All @@ -88,6 +88,8 @@ def main() -> int:
DETECT_TARGET_WORKER_COUNT = config["detect_target"]["worker_count"]
DETECT_TARGET_OPTION_INT = config["detect_target"]["option"]
DETECT_TARGET_OPTION = detect_target_factory.DetectTargetOption(DETECT_TARGET_OPTION_INT)
DETECT_TARGET_OPTION_INT = config["detect_target"]["option"]
DETECT_TARGET_OPTION = detect_target_factory.DetectTargetOption(DETECT_TARGET_OPTION_INT)
DETECT_TARGET_DEVICE = "cpu" if args.cpu else config["detect_target"]["device"]
DETECT_TARGET_MODEL_PATH = config["detect_target"]["model_path"]
DETECT_TARGET_OVERRIDE_FULL_PRECISION = args.full
Expand All @@ -113,9 +115,13 @@ def main() -> int:
GEOLOCATION_CAMERA_ORIENTATION_PITCH = config["geolocation"]["camera_orientation_pitch"]
GEOLOCATION_CAMERA_ORIENTATION_ROLL = config["geolocation"]["camera_orientation_roll"]

MIN_ACTIVATION_THRESHOLD = config["cluster_merge"]["min_activation_threshold"]
MIN_NEW_POINTS_TO_RUN = config["cluster_merge"]["min_new_points_to_run"]
RANDOM_STATE = config["cluster_merge"]["random_state"]
MIN_ACTIVATION_THRESHOLD = config["cluster_estimation"]["min_activation_threshold"]
MIN_NEW_POINTS_TO_RUN = config["cluster_estimation"]["min_new_points_to_run"]
RANDOM_STATE = config["cluster_estimation"]["random_state"]

MIN_ACTIVATION_THRESHOLD = config["cluster_estimation"]["min_activation_threshold"]
MIN_NEW_POINTS_TO_RUN = config["cluster_estimation"]["min_new_points_to_run"]
RANDOM_STATE = config["cluster_estimation"]["random_state"]
# pylint: enable=invalid-name
except KeyError as exception:
main_logger.error(f"Config key(s) not found: {exception}", True)
Expand Down Expand Up @@ -420,7 +426,8 @@ def main() -> int:
geolocation_data = geolocation_to_cluster_estimation_queue.queue.get_nowait()
geolocation_data = geolocation_to_cluster_estimation_queue.queue.get_nowait()
except queue.Empty:
geolocation_data = None
cluster_estimation_data = None
cluster_estimation_data = None

if geolocation_data is not None:
for detection_world in geolocation_data:
Expand Down
2 changes: 1 addition & 1 deletion modules/common
Submodule common updated 82 files
+2 −2 .gitmodules
+0 −57 kml/modules/location_ground.py
+0 −168 mavlink/modules/drone_odometry.py
+0 −0 modules/__init__.py
+0 −0 modules/camera/__init__.py
+0 −0 modules/camera/camera_device.py
+0 −0 modules/image_encoding/__init__.py
+1 −1 modules/image_encoding/decoder.py
+1 −1 modules/image_encoding/encoder.py
+0 −0 modules/kml/__init__.py
+15 −21 modules/kml/ground_locations_to_kml.py
+56 −0 modules/kml/named_location_global.py
+44 −0 modules/location_global.py
+42 −0 modules/location_local.py
+0 −0 modules/logger/__init__.py
+1 −1 modules/logger/config_logger.yaml
+211 −0 modules/logger/log_file_merger_helpers.py
+84 −0 modules/logger/log_file_merger_main.py
+1 −1 modules/logger/logger.py
+0 −0 modules/logger/logger_main_setup.py
+0 −0 modules/mavlink/__init__.py
+77 −0 modules/mavlink/drone_odometry_global.py
+57 −0 modules/mavlink/drone_odometry_local.py
+0 −0 modules/mavlink/dronekit
+42 −23 modules/mavlink/flight_controller.py
+121 −0 modules/mavlink/local_global_conversion.py
+0 −0 modules/network/README.md
+0 −0 modules/network/__init__.py
+0 −0 modules/network/tcp/__init__.py
+0 −0 modules/network/tcp/client_socket.py
+0 −0 modules/network/tcp/server_socket.py
+0 −0 modules/network/tcp/socket_wrapper.py
+0 −0 modules/network/udp/__init__.py
+0 −0 modules/network/udp/client_socket.py
+0 −0 modules/network/udp/server_socket.py
+1 −0 modules/network/udp/socket_wrapper.py
+65 −0 modules/orientation.py
+48 −0 modules/position_global.py
+48 −0 modules/position_local.py
+0 −0 modules/qr/__init__.py
+0 −0 modules/qr/qr_scanner.py
+0 −0 modules/read_yaml/__init__.py
+0 −0 modules/read_yaml/read_yaml.py
+0 −0 network/modules/udp/__init__.py
+2 −2 pyproject.toml
+0 −0 qr/__init__.py
+0 −0 qr/modules/__init__.py
+6 −0 requirements.txt
+1 −1 setup.cfg
+2 −3 setup_project.ps1
+0 −1 setup_project.sh
+65 −0 test_connection.py
+78 −0 test_undervoltage.py
+0 −0 tests/__init__.py
+0 −0 tests/integration/__init__.py
+0 −0 tests/integration/network/__init__.py
+1 −1 tests/integration/network/start_tcp_receiver.py
+1 −1 tests/integration/network/start_tcp_sender.py
+1 −1 tests/integration/network/start_udp_receiver.py
+1 −1 tests/integration/network/start_udp_sender.py
+2 −2 tests/integration/test_camera.py
+2 −2 tests/integration/test_camera_qr_example.py
+6 −6 tests/integration/test_flight_controller.py
+3 −3 tests/integration/test_flight_controller_mission_ended.py
+0 −0 tests/unit/__init__.py
+ tests/unit/image_encoding_images/test.png
+0 −0 tests/unit/kml_documents/expected_document.kml
+0 −0 tests/unit/network/__init__.py
+11 −5 tests/unit/network/test_send_image.py
+11 −1 tests/unit/network/test_tcp.py
+11 −1 tests/unit/network/test_udp.py
+ tests/unit/qr_images/2023_task1_diversion.png
+ tests/unit/qr_images/2023_task1_route.png
+ tests/unit/qr_images/2023_task2_routes.png
+0 −0 tests/unit/read_yaml_configs/config_no_error.yaml
+26 −8 tests/unit/test_ground_locations_to_kml.py
+12 −8 tests/unit/test_image_encode_decode.py
+120 −0 tests/unit/test_local_global_conversion.py
+336 −0 tests/unit/test_log_file_merger.py
+9 −5 tests/unit/test_logger.py
+2 −2 tests/unit/test_qr.py
+8 −11 tests/unit/test_read_yaml.py
26 changes: 24 additions & 2 deletions modules/data_merge/data_merge_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
Merges detections and telemetry by time.
"""

import os
import pathlib
import queue

from utilities.workers import queue_proxy_wrapper
from utilities.workers import worker_controller
from .. import detections_and_time
from .. import merged_odometry_detections
from .. import odometry_and_time
from ..common.modules.logger import logger


def data_merge_worker(
Expand All @@ -28,7 +31,14 @@ def data_merge_worker(
Merge work is done in the worker process as the queues and control mechanisms
are naturally available.
"""
# TODO: Logging?
worker_name = pathlib.Path(__file__).stem
process_id = os.getpid()
result, local_logger = logger.Logger.create(f"{worker_name}_{process_id}", True)
if not result:
print("ERROR: Worker failed to create logger")
return

assert local_logger is not None

# Mitigate potential deadlock caused by early program exit
try:
Expand All @@ -39,7 +49,7 @@ def data_merge_worker(
timeout=timeout,
)
except queue.Empty:
print("ERROR: Queue timed out on startup")
local_logger.error("Queue timed out on startup", True)
return

while not controller.is_exit_requested():
Expand Down Expand Up @@ -72,15 +82,27 @@ def data_merge_worker(
previous_odometry.odometry_data,
detections.detections,
)

odometry_timestamp = previous_odometry.timestamp
else:
result, merged = merged_odometry_detections.MergedOdometryDetections.create(
current_odometry.odometry_data,
detections.detections,
)

odometry_timestamp = current_odometry.timestamp

local_logger.info(
f"Odometry timestamp: {odometry_timestamp}, detections timestamp: {detections.timestamp}, detections - odometry: {detections.timestamp - odometry_timestamp}",
True,
)

if not result:
local_logger.warning("Failed to create merged odometry and detections", True)
continue

local_logger.info(str(merged), True)

# Get Pylance to stop complaining
assert merged is not None

Expand Down
28 changes: 16 additions & 12 deletions modules/decision/landing_pad_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@ def mark_confirmed_positive(self, detection: object_in_world.ObjectInWorld) -> N

def run(
self, detections: "list[object_in_world.ObjectInWorld]"
) -> "tuple[bool, object_in_world.ObjectInWorld | None]":
) -> "tuple[bool, list[object_in_world.ObjectInWorld] | None]":
"""
Updates the list of unconfirmed positives and returns the a first confirmed positive if
one exists, else the unconfirmed positive with the lowest variance.
Updates the list of unconfirmed positives and returns the confirmed positives if
they exist, otherwise returns the unconfirmed positives.
detections: New detections.
Return: List of confirmed/unconfirmed positives.
"""
for detection in detections:
match_found = False
Expand All @@ -82,16 +86,16 @@ def run(
# If new landing pad, add to list of unconfirmed positives
self.__unconfirmed_positives.append(detection)

# If there are confirmed positives, return the first one
# If there are confirmed positives, return them
if len(self.__confirmed_positives) > 0:
return True, self.__confirmed_positives[0]
return True, self.__confirmed_positives

# If the list is empty, all landing pads have been visited, none are viable
if len(self.__unconfirmed_positives) == 0:
return False, None
# If there are unconfirmed positives, return them
if len(self.__unconfirmed_positives) > 0:
# Sort list by variance in ascending order
self.__unconfirmed_positives.sort(key=lambda x: x.spherical_variance)

# Sort list by variance in ascending order
self.__unconfirmed_positives.sort(key=lambda x: x.spherical_variance)
return True, self.__unconfirmed_positives

# Return detection with lowest variance
return True, self.__unconfirmed_positives[0]
# All landing pads have been visited, none are viable
return False, None
2 changes: 1 addition & 1 deletion modules/detect_target/detect_target_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from utilities.workers import queue_proxy_wrapper
from utilities.workers import worker_controller
from . import detect_target_factory
from ..common.logger.modules import logger
from ..common.modules.logger import logger


def detect_target_worker(
Expand Down
9 changes: 7 additions & 2 deletions modules/detections_and_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,15 @@ def __str__(self) -> str:
To string.
"""
return (
f"{self.__class__}, time: {int(self.timestamp)}, size: {len(self)}\n"
+ f"{self.detections}"
f"{self.__class__}, time: {self.timestamp}, size: {len(self)}\n" + f"{self.detections}"
)

def __repr__(self) -> str:
"""
For collections (e.g. list).
"""
return str(self)

def __len__(self) -> int:
"""
Gets the number of detected objects.
Expand Down
Loading

0 comments on commit 5001a51

Please sign in to comment.