赞
踩
LQR路径跟踪要求路径中带角度,即坐标(x,y,yaw),而一般我们的规划出来的路径不带角度。这里通过总结相关方法,并提供一个案例。
将点路径拟合成一条完整的线路径是一个常见的问题,在计算机图形学、机器人导航、地图制作等领域都有广泛的应用。以下是一些常见的用于路径拟合的算法:
以上算法各有特点,选择合适的方法取决于具体的应用场景、路径形状和性能要求。在实际应用中,通常会结合多种算法来完成路径拟合任务。
#include <iostream> #include <Eigen/Dense> #include <opencv2/opencv.hpp> using namespace cv; // 多项式拟合函数 Eigen::VectorXd polynomialFit(const Eigen::VectorXd& x, const Eigen::VectorXd& y, int degree) { int n = x.size(); Eigen::MatrixXd A(n, degree + 1); // 构建系数矩阵 A for (int i = 0; i < n; ++i) { for (int j = 0; j <= degree; ++j) { A(i, j) = pow(x(i), j); } } // 使用最小二乘法求解系数 return A.householderQr().solve(y); } int main() { // 构造示例数据 Eigen::VectorXd x(5); Eigen::VectorXd y(5); x << 0, 1, 2, 3, 4; y << 0, 1, 4, 9, 16; // 进行二次多项式拟合 int degree = 2; Eigen::VectorXd coeffs = polynomialFit(x, y, degree); // 打印拟合的多项式系数 std::cout << "拟合的多项式系数:" << coeffs.transpose() << std::endl; // 绘制拟合的曲线和原始数据 Mat img(300, 300, CV_8UC3, Scalar(255, 255, 255)); for (int i = 0; i < img.cols/5; ++i) { double y_fit = 0; for (int j = 0; j <= degree; ++j) { y_fit += coeffs(j) * pow(i, j); } Point pt(i*5, y_fit*5); circle(img, pt, 1, Scalar(0, 0, 255), FILLED); // 绘制拟合的曲线,使用红色 } for (int i = 0; i < x.size(); ++i) { Point pt(x(i)*5, y(i)*5); // 缩放原始数据,以便在图像中显示 circle(img, pt, 3, Scalar(0, 255, 0), FILLED); // 绘制原始数据,使用绿色 } // 显示结果 imshow("Polynomial Fit with Original Data", img); waitKey(0); return 0; }
上面的方法如果是在仿真中太麻烦,可以用一个特殊函数代替路径如sin(t)函数直接生成轨迹,并可以通过求导的方法计算yaw值。
#include <iostream> #include <cmath> double curvature(double t) { // 计算 sin(t) 关于 t 的一阶导数 double dx_dt = cos(t); // 计算 sin(t) 关于 t 的二阶导数 double d2x_dt2 = -sin(t); // 计算曲率 double curvature = std::abs(d2x_dt2) / pow(1 + pow(dx_dt, 2), 1.5); return curvature; } double slopeAngle(double t) { // 计算 sin(t) 关于 t 的一阶导数 double dx_dt = cos(t); // 计算斜率的角度(以弧度为单位) double angle = atan2(dx_dt); return angle; } int main() { // 设定时刻 t0 double t0 = 0.5; // 例如,这里设定 t0 为 0.5 // 计算曲率 double curv = curvature(t0); // 计算斜率角度 double angle = slopeAngle(t0); // 输出结果 std::cout << "sin(" << t0 << ") 函数在时刻 t=" << t0 << " 的曲率为: " << curv << std::endl; std::cout << "sin(" << t0 << ") 函数在时刻 t=" << t0 << " 的斜率角度为: " << angle << " 弧度" << std::endl; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。