From 3809d92c538910a392de326c8f5b453eaf21e296 Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 11:00:30 -0600 Subject: [PATCH 01/10] Changed constants to parameters and added to NavigationParameters class --- src/navigator/navigator_node/main.py | 23 +++++++++++++++++++---- src/navigator/navigator_node/types.py | 11 +++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index 0fdb92a6..fdf5f0a1 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -637,8 +637,23 @@ async def _handle_search_mode( Returns the current navigation task. """ - SEARCH_RADIUS = 10.0 # meters - TODO: Make this a parameter - SEARCH_POINTS = 10 # TODO: Make this a parameter + + self.declare_parameter("search_radius", 10.0) + self.declare_parameter("search_points", 10) + + search_radius = self.get_parameter("search_radius").value + search_points = self.get_parameter("search_points").value + + self.nav_params = NavigationParameters( + search_radius=search_radius, + search_points=search_points, + ) + + if search_radius <= 0: + raise ValueError("Radius must be positive") + + if search_points < 3: + raise ValueError("Must have 3 or more points to make circle") # Check if queue empty if coordinate_queue.empty(): @@ -647,8 +662,8 @@ async def _handle_search_mode( similar_coords = generate_similar_coordinates( current_location, - radius=SEARCH_RADIUS, - num_points=SEARCH_POINTS, + radius=self.nav_params.search_radius, + num_points=self.nav_params.search_points, ) # Add coordinates to queue, prioritized by distance to current location diff --git a/src/navigator/navigator_node/types.py b/src/navigator/navigator_node/types.py index a4abb056..0162bb84 100644 --- a/src/navigator/navigator_node/types.py +++ b/src/navigator/navigator_node/types.py @@ -12,6 +12,17 @@ class NavigationMode(Enum): @dataclass(kw_only=True) class NavigationParameters: + search_radius: float + """ + The radius of the circle we want the Rover to drive around. + """ + + search_points: int + """ + How many coordinates to generate (i.e. how many points should the circle + of coordinates be made of) + """ + coord: GeoPoint """ The coordinate that either is our goal (if `mode` is `GPS`), or is some From 3f3394cd2081b1d8b9c6f721c0c5663b37eec32f Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 11:21:51 -0600 Subject: [PATCH 02/10] Fixed formatting --- src/navigator/navigator_node/main.py | 2 +- src/navigator/navigator_node/types.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index fdf5f0a1..8510e989 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -651,7 +651,7 @@ async def _handle_search_mode( if search_radius <= 0: raise ValueError("Radius must be positive") - + if search_points < 3: raise ValueError("Must have 3 or more points to make circle") diff --git a/src/navigator/navigator_node/types.py b/src/navigator/navigator_node/types.py index 0162bb84..79709239 100644 --- a/src/navigator/navigator_node/types.py +++ b/src/navigator/navigator_node/types.py @@ -16,7 +16,7 @@ class NavigationParameters: """ The radius of the circle we want the Rover to drive around. """ - + search_points: int """ How many coordinates to generate (i.e. how many points should the circle From 9557df8a112da5fb331f81cd55a6c14441b9d087 Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 12:04:06 -0600 Subject: [PATCH 03/10] Potential fixes for Pyright errors --- src/navigator/navigator_node/main.py | 8 ++++---- src/navigator/navigator_node/types.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index 8510e989..1a476bc4 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -638,11 +638,11 @@ async def _handle_search_mode( Returns the current navigation task. """ - self.declare_parameter("search_radius", 10.0) - self.declare_parameter("search_points", 10) + _ = self.declare_parameter("search_radius", 10.0) + _ = self.declare_parameter("search_points", 10) - search_radius = self.get_parameter("search_radius").value - search_points = self.get_parameter("search_points").value + search_radius = float(self.get_parameter("search_radius").value) + search_points = int(self.get_parameter("search_points").value) self.nav_params = NavigationParameters( search_radius=search_radius, diff --git a/src/navigator/navigator_node/types.py b/src/navigator/navigator_node/types.py index 79709239..760f6032 100644 --- a/src/navigator/navigator_node/types.py +++ b/src/navigator/navigator_node/types.py @@ -12,18 +12,18 @@ class NavigationMode(Enum): @dataclass(kw_only=True) class NavigationParameters: - search_radius: float + search_radius: float | None = None """ The radius of the circle we want the Rover to drive around. """ - search_points: int + search_points: int | None = None """ How many coordinates to generate (i.e. how many points should the circle of coordinates be made of) """ - coord: GeoPoint + coord: GeoPoint | None = None """ The coordinate that either is our goal (if `mode` is `GPS`), or is some point around an ArUco marker or an object. @@ -37,7 +37,7 @@ class NavigationParameters: https://docs.opencv.org/3.4/d9/d6a/group__aruco.html#ggac84398a9ed9dd01306592dd616c2c975ada8e830ff0024e839e93c01f5fed0c55 """ - mode: NavigationMode + mode: NavigationMode | None = None """ Indicates what the Navigator is doing. From 67037b6e854ae0a5e37a70a3971c7a7487c412f3 Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 15:01:05 -0600 Subject: [PATCH 04/10] Second attempted fix for pyright stuff --- src/navigator/navigator_node/main.py | 43 +++++++++++++++------------ src/navigator/navigator_node/types.py | 7 ++--- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index 1a476bc4..c96b95d0 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -170,10 +170,32 @@ def __init__(self): ) sys.exit(1) + # Declare search parameters + _ = self.declare_parameter("search_radius", 10.0) + _ = self.declare_parameter("search_points", 10) + + search_radius_raw = self.get_parameter("search_radius").value + search_points_raw = self.get_parameter("search_points").value + + if search_radius_raw is None or search_points_raw is None: + self.get_logger().error("No search paramaters set") + sys.exit(1) + + search_radius = float(search_radius_raw) + search_points = int(search_points_raw) + + if search_radius <= 0: + raise ValueError("Radius must be positive") + + if search_points < 3: + raise ValueError("Must be 3 or more points to create circle") + # construct the parameters self.nav_parameters = NavigationParameters( coord=coord, mode=NavigationMode(mode_int), + search_radius=search_radius, + search_points=search_points ) _ = self.get_logger().debug("constructed all parameters.") @@ -638,23 +660,6 @@ async def _handle_search_mode( Returns the current navigation task. """ - _ = self.declare_parameter("search_radius", 10.0) - _ = self.declare_parameter("search_points", 10) - - search_radius = float(self.get_parameter("search_radius").value) - search_points = int(self.get_parameter("search_points").value) - - self.nav_params = NavigationParameters( - search_radius=search_radius, - search_points=search_points, - ) - - if search_radius <= 0: - raise ValueError("Radius must be positive") - - if search_points < 3: - raise ValueError("Must have 3 or more points to make circle") - # Check if queue empty if coordinate_queue.empty(): # Generate new search coordinates around current location @@ -662,8 +667,8 @@ async def _handle_search_mode( similar_coords = generate_similar_coordinates( current_location, - radius=self.nav_params.search_radius, - num_points=self.nav_params.search_points, + radius=self.nav_parameters.search_radius, + num_points=self.nav_parameters.search_points, ) # Add coordinates to queue, prioritized by distance to current location diff --git a/src/navigator/navigator_node/types.py b/src/navigator/navigator_node/types.py index 760f6032..fa3d7c3d 100644 --- a/src/navigator/navigator_node/types.py +++ b/src/navigator/navigator_node/types.py @@ -1,6 +1,5 @@ from dataclasses import dataclass from enum import Enum - from geographic_msgs.msg import GeoPoint @@ -12,18 +11,18 @@ class NavigationMode(Enum): @dataclass(kw_only=True) class NavigationParameters: - search_radius: float | None = None + search_radius: float """ The radius of the circle we want the Rover to drive around. """ - search_points: int | None = None + search_points: int """ How many coordinates to generate (i.e. how many points should the circle of coordinates be made of) """ - coord: GeoPoint | None = None + coord: GeoPoint """ The coordinate that either is our goal (if `mode` is `GPS`), or is some point around an ArUco marker or an object. From 258131d8f633d78915dcd549c3db87c1abac20e6 Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 15:04:20 -0600 Subject: [PATCH 05/10] Fixed formatting again --- src/navigator/navigator_node/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index c96b95d0..7b61e782 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -186,7 +186,7 @@ def __init__(self): if search_radius <= 0: raise ValueError("Radius must be positive") - + if search_points < 3: raise ValueError("Must be 3 or more points to create circle") @@ -195,7 +195,7 @@ def __init__(self): coord=coord, mode=NavigationMode(mode_int), search_radius=search_radius, - search_points=search_points + search_points=search_points, ) _ = self.get_logger().debug("constructed all parameters.") From 3375161fce2d94a819ceca303e87468885d7c01d Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 17:02:25 -0600 Subject: [PATCH 06/10] Pywright fix attempt 3 --- src/navigator/navigator_node/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index 7b61e782..4cb6f7ad 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -178,7 +178,9 @@ def __init__(self): search_points_raw = self.get_parameter("search_points").value if search_radius_raw is None or search_points_raw is None: - self.get_logger().error("No search paramaters set") + self.get_logger().error( + "No search paramaters set." + ) sys.exit(1) search_radius = float(search_radius_raw) From 4c51fff8d5b9e8d181d1855dbade07e0b833fc35 Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 17:05:25 -0600 Subject: [PATCH 07/10] Formatted again --- src/navigator/navigator_node/main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index 4cb6f7ad..c22090d6 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -178,9 +178,7 @@ def __init__(self): search_points_raw = self.get_parameter("search_points").value if search_radius_raw is None or search_points_raw is None: - self.get_logger().error( - "No search paramaters set." - ) + self.get_logger().error("No search paramaters set.") sys.exit(1) search_radius = float(search_radius_raw) From 59e7cf124c9e56b1d5b67c011c11052b6365073e Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 17:13:12 -0600 Subject: [PATCH 08/10] Pywright fixes --- src/navigator/navigator_node/main.py | 2 +- src/navigator/navigator_node/types.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index c22090d6..445c3f6d 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -179,7 +179,7 @@ def __init__(self): if search_radius_raw is None or search_points_raw is None: self.get_logger().error("No search paramaters set.") - sys.exit(1) + raise SystemExit(1) search_radius = float(search_radius_raw) search_points = int(search_points_raw) diff --git a/src/navigator/navigator_node/types.py b/src/navigator/navigator_node/types.py index fa3d7c3d..14eefc08 100644 --- a/src/navigator/navigator_node/types.py +++ b/src/navigator/navigator_node/types.py @@ -36,7 +36,7 @@ class NavigationParameters: https://docs.opencv.org/3.4/d9/d6a/group__aruco.html#ggac84398a9ed9dd01306592dd616c2c975ada8e830ff0024e839e93c01f5fed0c55 """ - mode: NavigationMode | None = None + mode: NavigationMode """ Indicates what the Navigator is doing. From 7bd0b45997d537973c487446816f68429f3a8c0c Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 17:19:59 -0600 Subject: [PATCH 09/10] More Pywright fixes --- src/navigator/navigator_node/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index 445c3f6d..fedac2ff 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -178,7 +178,7 @@ def __init__(self): search_points_raw = self.get_parameter("search_points").value if search_radius_raw is None or search_points_raw is None: - self.get_logger().error("No search paramaters set.") + _ = self.get_logger().error("No search paramaters set.") raise SystemExit(1) search_radius = float(search_radius_raw) From 64742d36d74d84bddf59b7bb4998097a421a09e9 Mon Sep 17 00:00:00 2001 From: Carson Burnett Date: Fri, 20 Feb 2026 18:02:56 -0600 Subject: [PATCH 10/10] Marker Missed Threshold Parameter implemented --- src/navigator/navigator_node/main.py | 18 ++++++++++++++++-- src/navigator/navigator_node/types.py | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/navigator/navigator_node/main.py b/src/navigator/navigator_node/main.py index fedac2ff..4a45d641 100644 --- a/src/navigator/navigator_node/main.py +++ b/src/navigator/navigator_node/main.py @@ -190,12 +190,27 @@ def __init__(self): if search_points < 3: raise ValueError("Must be 3 or more points to create circle") + # Marker Missed Threshold parameter + _ = self.declare_parameter("marker_missed_threshold", 20) + + threshold_raw = self.get_parameter("marker_missed_threshold").value + + if threshold_raw is None: + _ = self.get_logger().error("marker_missed_threshold not set") + raise SystemExit(1) + + marker_missed_threshold = int(threshold_raw) + + if marker_missed_threshold <= 0: + raise ValueError("Threshold must be positive") + # construct the parameters self.nav_parameters = NavigationParameters( coord=coord, mode=NavigationMode(mode_int), search_radius=search_radius, search_points=search_points, + marker_missed_threshold=marker_missed_threshold, ) _ = self.get_logger().debug("constructed all parameters.") @@ -624,10 +639,9 @@ async def _handle_marker_lost( Returns updated values for parent function. """ - MARKER_MISSED_THRESHOLD = 20 # TODO: Make this a parameter # If missed count is too high, cancel current search task and stop tracking - if marker_missed_count > MARKER_MISSED_THRESHOLD: + if marker_missed_count > self.nav_parameters.marker_missed_threshold: llogger.warning( f"Marker lost after {marker_missed_count} consecutive missed detections. \ Resuming search pattern." diff --git a/src/navigator/navigator_node/types.py b/src/navigator/navigator_node/types.py index 14eefc08..ca2619a5 100644 --- a/src/navigator/navigator_node/types.py +++ b/src/navigator/navigator_node/types.py @@ -43,3 +43,9 @@ class NavigationParameters: For example, if we're given `NavigationMode::GPS`, we'll navigate to the given GPS coordinate and stop when we're there. """ + + marker_missed_threshold: int + """ + Decides how many times a marker is missed before we decide that us seeing it + was a false positive and we stop trying to track it. + """