Skip to content

Commit 65cd161

Browse files
Merge pull request #205 from pranavreddy23/pathfinder
Pathfinder
2 parents 22b8f7d + 1f7a99d commit 65cd161

14 files changed

Lines changed: 1445 additions & 448 deletions

File tree

VisionPilot/Production_Releases/0.5/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
77
# Find dependencies
88
find_package(OpenCV REQUIRED)
99
find_package(Threads REQUIRED)
10+
find_package(Eigen3 REQUIRED)
1011

1112
# ONNX Runtime - user must set ONNXRUNTIME_ROOT
1213
if(NOT DEFINED ENV{ONNXRUNTIME_ROOT})
@@ -35,6 +36,7 @@ include_directories(
3536
include
3637
${OpenCV_INCLUDE_DIRS}
3738
${ONNXRUNTIME_INCLUDE_DIR}
39+
${EIGEN3_INCLUDE_DIR}
3840
)
3941

4042
# AutoSteer inference backend
@@ -80,6 +82,25 @@ target_link_libraries(camera_utils
8082
${OpenCV_LIBS}
8183
)
8284

85+
# Path planning module (polynomial fitting + Bayes filter)
86+
add_library(path_planning
87+
src/path_planning/estimator.cpp
88+
src/path_planning/poly_fit.cpp
89+
src/path_planning/path_finder.cpp
90+
)
91+
target_link_libraries(path_planning
92+
${OpenCV_LIBS}
93+
Eigen3::Eigen
94+
)
95+
96+
# Steering control module
97+
add_library(steering_control
98+
src/steering_control/steering_controller.cpp
99+
)
100+
target_link_libraries(steering_control
101+
# No external dependencies, pure C++ math
102+
)
103+
83104
# Rerun SDK (optional, for visualization/logging)
84105
option(ENABLE_RERUN "Enable Rerun logging and visualization" OFF)
85106

@@ -152,6 +173,8 @@ set(AUTOSTEER_LIBS
152173
autosteer_lane_filtering
153174
autosteer_lane_tracking
154175
camera_utils
176+
path_planning
177+
steering_control
155178
${OpenCV_LIBS}
156179
pthread
157180
)

VisionPilot/Production_Releases/0.5/include/lane_tracking/lane_tracking.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ struct BEVVisuals {
1414
std::vector<double> bev_left_coeffs; // BEV egoleft coeffs
1515
std::vector<double> bev_right_coeffs; // BEV egoright coeffs
1616
std::vector<double> bev_center_coeffs;// BEV drivable corridor coeffs
17+
18+
// BEV lane points in pixel space (for PathFinder)
19+
std::vector<cv::Point2f> bev_left_pts; // Left lane points in BEV pixels
20+
std::vector<cv::Point2f> bev_right_pts; // Right lane points in BEV pixels
21+
1722
double last_valid_width_pixels = 0.0; // Width bar
1823
bool valid = false;
1924
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @file estimator.hpp
3+
* @brief Bayes filter for temporal tracking of lane parameters
4+
*
5+
* Ported from PATHFINDER ROS2 package (no ROS2 dependencies)
6+
*/
7+
8+
#pragma once
9+
10+
#include <vector>
11+
#include <array>
12+
#include <cmath>
13+
14+
constexpr size_t STATE_DIM = 14;
15+
16+
struct Gaussian
17+
{
18+
double mean;
19+
double variance;
20+
};
21+
22+
class Estimator
23+
{
24+
private:
25+
std::array<Gaussian, STATE_DIM> state;
26+
std::vector<std::pair<size_t, size_t>> fusion_rules;
27+
28+
public:
29+
void initialize(const std::array<Gaussian, STATE_DIM> &init_state);
30+
void predict(const std::array<Gaussian, STATE_DIM> &process);
31+
void update(const std::array<Gaussian, STATE_DIM> &measurement);
32+
void configureFusionGroups(const std::vector<std::pair<size_t, size_t>> &rules);
33+
const std::array<Gaussian, STATE_DIM> &getState() const;
34+
};
35+
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/**
2+
* @file path_finder.hpp
3+
* @brief Standalone PathFinder module (no ROS2)
4+
*
5+
* Integrates polynomial fitting and Bayes filter for robust lane tracking
6+
*/
7+
8+
#pragma once
9+
10+
#include "path_planning/poly_fit.hpp"
11+
#include "path_planning/estimator.hpp"
12+
#include <opencv2/opencv.hpp>
13+
#include <vector>
14+
#include <array>
15+
#include <string>
16+
17+
namespace autoware_pov::vision::path_planning {
18+
19+
/**
20+
* @brief Output of PathFinder module
21+
*/
22+
struct PathFinderOutput
23+
{
24+
// Fused metrics from Bayes filter (temporally smoothed)
25+
double cte; // Cross-track error (meters)
26+
double yaw_error; // Yaw error (radians)
27+
double curvature; // Curvature (1/meters)
28+
double lane_width; // Corridor width (meters)
29+
30+
// Confidence (variance from Bayes filter)
31+
double cte_variance;
32+
double yaw_variance;
33+
double curv_variance;
34+
double lane_width_variance;
35+
36+
// Raw polynomial coefficients (for debugging/visualization)
37+
std::array<double, 3> left_coeff; // x = c0*y² + c1*y + c2
38+
std::array<double, 3> right_coeff; // x = c0*y² + c1*y + c2
39+
std::array<double, 3> center_coeff; // Average of left and right
40+
41+
// Individual curve metrics (before fusion)
42+
double left_cte;
43+
double left_yaw_error;
44+
double left_curvature;
45+
double right_cte;
46+
double right_yaw_error;
47+
double right_curvature;
48+
49+
// Validity flags
50+
bool left_valid;
51+
bool right_valid;
52+
bool fused_valid;
53+
};
54+
55+
/**
56+
* @brief PathFinder for lane tracking and trajectory estimation
57+
*
58+
* Features:
59+
* - Polynomial fitting to BEV lane points (in meters)
60+
* - Temporal smoothing via Bayes filter
61+
* - Robust fusion of left/right lanes
62+
*
63+
* Note: Expects BEV points already in metric coordinates (meters)
64+
*/
65+
class PathFinder
66+
{
67+
public:
68+
/**
69+
* @brief Initialize PathFinder
70+
* @param default_lane_width Default lane width in meters (default: 4.0)
71+
*/
72+
explicit PathFinder(double default_lane_width = 4.0);
73+
74+
/**
75+
* @brief Update with new lane detections
76+
*
77+
* @param left_pts_bev Left lane points in BEV meters (x=lateral, y=longitudinal)
78+
* @param right_pts_bev Right lane points in BEV meters
79+
* @return PathFinder output (fused metrics + individual curves)
80+
*/
81+
PathFinderOutput update(
82+
const std::vector<cv::Point2f>& left_pts_bev,
83+
const std::vector<cv::Point2f>& right_pts_bev);
84+
85+
/**
86+
* @brief Get current tracked state
87+
* @return Current Bayes filter state (all 14 variables)
88+
*/
89+
const std::array<Gaussian, STATE_DIM>& getState() const;
90+
91+
/**
92+
* @brief Reset Bayes filter to initial state
93+
*/
94+
void reset();
95+
96+
private:
97+
double default_lane_width_;
98+
Estimator bayes_filter_;
99+
100+
// Tuning parameters (from PATHFINDER)
101+
const double PROC_SD = 0.5; // Process noise
102+
const double STD_M_CTE = 0.1; // CTE measurement std (m)
103+
const double STD_M_YAW = 0.01; // Yaw measurement std (rad)
104+
const double STD_M_CURV = 0.1; // Curvature measurement std (1/m)
105+
const double STD_M_WIDTH = 0.01; // Width measurement std (m)
106+
107+
/**
108+
* @brief Initialize Bayes filter
109+
*/
110+
void initializeBayesFilter();
111+
};
112+
113+
} // namespace autoware_pov::vision::path_planning
114+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @file poly_fit.hpp
3+
* @brief Polynomial fitting and lane curve utilities
4+
*
5+
* Extracted from PATHFINDER package's path_finder.hpp/cpp
6+
*/
7+
8+
#pragma once
9+
10+
#include <opencv2/opencv.hpp>
11+
#include <array>
12+
#include <vector>
13+
14+
namespace autoware_pov::vision::path_planning {
15+
16+
/**
17+
* @brief Fitted quadratic curve: x = c0*y² + c1*y + c2
18+
*
19+
* Vehicle-centric BEV coordinates:
20+
* - x: lateral position (positive = right)
21+
* - y: longitudinal position (positive = forward)
22+
*/
23+
struct FittedCurve
24+
{
25+
std::array<double, 3> coeff; // [c0, c1, c2] for x = c0*y² + c1*y + c2
26+
double cte; // Cross-track error at y=0 (meters)
27+
double yaw_error; // Yaw error at y=0 (radians)
28+
double curvature; // Curvature at y=0 (meters^-1)
29+
30+
FittedCurve();
31+
explicit FittedCurve(const std::array<double, 3> &coeff);
32+
};
33+
34+
/**
35+
* @brief Fit quadratic polynomial to BEV points
36+
*
37+
* Fits x = c0*y² + c1*y + c2 using least squares
38+
*
39+
* @param points BEV points in meters (x=lateral, y=longitudinal)
40+
* @return Coefficients [c0, c1, c2], or NaN if insufficient points
41+
*/
42+
std::array<double, 3> fitQuadPoly(const std::vector<cv::Point2f> &points);
43+
44+
/**
45+
* @brief Calculate center lane from left and right lanes
46+
*
47+
* Averages the polynomial coefficients
48+
*
49+
* @param left_lane Left lane curve
50+
* @param right_lane Right lane curve
51+
* @return Center lane curve
52+
*/
53+
FittedCurve calculateEgoPath(const FittedCurve &left_lane, const FittedCurve &right_lane);
54+
55+
} // namespace autoware_pov::vision::path_planning
56+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @file steering_controller.hpp
3+
* @brief Steering controller for path following
4+
*
5+
* Combines Stanley controller (PI on CTE) with curvature feedforward
6+
* Input: CTE, yaw_error, forward_velocity, curvature (from PathFinder)
7+
* Output: Steering angle (radians)
8+
*/
9+
10+
#pragma once
11+
12+
#include <iostream>
13+
#include <cmath>
14+
15+
namespace autoware_pov::vision::steering_control {
16+
17+
/**
18+
* @brief Default steering controller parameters
19+
*/
20+
21+
namespace SteeringControllerDefaults {
22+
constexpr double K_P = 0.8; // Proportional gain for yaw error
23+
constexpr double K_I = 1.6; // Integral gain for CTE (Stanley controller)
24+
constexpr double K_D = 1.0; // Derivative gain for yaw error
25+
constexpr double K_S = 1.0; //proportionality constant for curvature
26+
};
27+
28+
class SteeringController
29+
{
30+
public:
31+
/**
32+
* @brief Constructor
33+
* @param K_p Proportional gain for yaw error
34+
* @param K_i Integral gain for CTE (Stanley controller)
35+
* @param K_d Derivative gain for yaw error
36+
* @param K_S Proportionality constant for curvature feedforward
37+
*/
38+
SteeringController(
39+
double K_p,
40+
double K_i,
41+
double K_d,
42+
double K_S);
43+
44+
45+
/**
46+
* @brief Compute steering angle
47+
* @param cte Cross-track error (meters)
48+
* @param yaw_error Yaw error (radians)
49+
* @param feed_forward_steering_estimate (angle in degrees)
50+
* @return Steering angle (radians)
51+
*/
52+
double computeSteering(double cte, double yaw_error, double feed_forward_steering_estimate);
53+
54+
private:
55+
double K_p, K_i, K_d, K_S;
56+
double prev_yaw_error;
57+
};
58+
59+
} // namespace autoware_pov::vision::steering_control
60+

VisionPilot/Production_Releases/0.5/include/visualization/draw_lanes.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ void drawBEVVis(
7777
const BEVVisuals& bev_data
7878
);
7979

80+
/**
81+
* @brief Debug function to verify Pixel -> Meter conversion
82+
* Draws the metric polynomials (projected back to pixels) on top of the BEV image.
83+
*/
84+
void drawMetricVerification(
85+
cv::Mat& bev_image,
86+
const std::vector<double>& left_metric_coeffs,
87+
const std::vector<double>& right_metric_coeffs
88+
);
89+
8090
} // namespace autoware_pov::vision::autosteer
8191

8292
#endif // AUTOWARE_POV_VISION_AUTOSTEER_DRAW_LANES_HPP_

0 commit comments

Comments
 (0)