Skip to content

Commit 70fd571

Browse files
committed
modify fit_curve_radius in trajectory.py to use the min (tighest) turn radius of the next 3 segments of 3 points
1 parent 20264fd commit 70fd571

1 file changed

Lines changed: 26 additions & 36 deletions

File tree

GEMstack/state/trajectory.py

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -167,51 +167,41 @@ def trim(self, start : float, end : float) -> Path:
167167

168168
def fit_curve_radius(self, vehicle_position: List[float], n_points: int) -> float:
169169
"""
170-
Fits a circular curve to n upcoming points from the vehicle's current position
171-
and returns the radius of that curve.
170+
Calculates the curve radius over the next 3 intervals and returns the largest.
172171
173172
Args:
174173
vehicle_position: Current position of the vehicle [x, y, ...]
175-
n_points: Number of upcoming points to consider for curve fitting
176-
174+
n_points: Number of points to sample ahead. Must be >= 5 to allow 3 intervals.
175+
177176
Returns:
178-
float: Radius of the fitted circular curve. Returns float('inf') for
179-
straight lines or when insufficient points are available.
177+
float: Min radius among 3 consecutive 3-point intervals. Returns float('inf') if not enough data.
180178
"""
181-
# Find the closest point on the path to the vehicle position
182179
_, closest_point_idx_float = self.closest_point(vehicle_position)
183-
184-
# I use ceil here because we want to be looking forward to the next set of points
185180
closest_point_idx = int(math.ceil(closest_point_idx_float))
186181

187-
# Get indices for n upcoming points
188-
start_idx = closest_point_idx
189-
end_idx = min(start_idx + n_points, len(self.points) - 1)
190-
191-
# If we don't have enough points for fitting, return infinite radius (straight line)
192-
if end_idx - start_idx < 2:
193-
return float('inf')
194-
182+
# Require at least 5 points to form 3 overlapping triplets
183+
total_needed = max(n_points, 5)
184+
end_idx = min(closest_point_idx + total_needed, len(self.points))
195185

196-
# Extract upcoming points for fitting
197-
points_to_fit = self.points[start_idx:end_idx+1]
198-
199-
# Ensure we have at least 3 points for circle fitting
200-
if len(points_to_fit) < 3:
201-
return float('inf')
202-
203-
# For now, we'll focus on 2D paths
204-
# If points are higher dimensional, we'll use only x,y coordinates
205-
points_2d = [[p[0], p[1]] for p in points_to_fit]
206-
207-
# Fit circle to points using least squares method
208-
try:
209-
# Center of circle (h, k) and radius r
210-
h, k, r = self._fit_circle_to_points(points_2d)
211-
return r
212-
except:
213-
# If fitting fails (e.g., collinear points), return infinite radius
214-
return float('inf')
186+
if end_idx - closest_point_idx < 5:
187+
return float('0')
188+
189+
# Get the next chunk of points
190+
points_to_check = self.points[closest_point_idx:end_idx]
191+
192+
# Convert to 2D
193+
points_2d = [[p[0], p[1]] for p in points_to_check]
194+
195+
radii = []
196+
for i in range(len(points_2d) - 2): # Slide a window of 3
197+
triplet = points_2d[i:i+3]
198+
try:
199+
_, _, r = self._fit_circle_to_points(triplet)
200+
radii.append(r)
201+
except:
202+
radii.append(float('inf')) # Treat failed fits as straight line
203+
204+
return min(radii) if radii else float('0')
215205

216206
def _fit_circle_to_points(self, points: List[List[float]]) -> Tuple[float, float, float]:
217207
"""

0 commit comments

Comments
 (0)