配置文件:

平滑器的配置文件
位置:

modules/planning/conf/planning.conf

–smoother_config_filename=/apollo/modules/planning/conf/discrete_points_smoother_config.pb.txt

内容:

max_constraint_interval : 0.25
longitudinal_boundary_bound : 2.0
max_lateral_boundary_bound : 0.5
min_lateral_boundary_bound : 0.1
curb_shift : 0.2
lateral_buffer : 0.2

discrete_points {
smoothing_method: FEM_POS_DEVIATION_SMOOTHING
fem_pos_deviation_smoothing {
weight_fem_pos_deviation: 1e10
weight_ref_deviation: 1.0
weight_path_length: 1.0
apply_curvature_constraint: false
max_iter: 500
time_limit: 0.0
verbose: false
scaled_termination: true
warm_start: true}
}
问题:

参考discretized_points_smoothing/fem_pos_deviation_smoother.h中的注释

/*

  • @brief:
  • This class solve an optimization problem:
  • Y
  • |
  • | P(x1, y1) P(x2, y2)
  • | P(x0, y0) … P(x(k-1), y(k-1))
  • |P(start)
  • |
  • |________________________________________________________ X
  • Given an initial set of points from 0 to k-1, The goal is to find a set of
  • points which makes the line P(start), P0, P(1) … P(k-1) “smooth”.
    */

平滑K个点即P0~PK-1。

方法:

在ReferenceLineProvider的构造函数中,有选择平滑器的相关代码:

if (smoother_config_.has_qp_spline()) {
smoother_.reset(new QpSplineReferenceLineSmoother(smoother_config_));
} else if (smoother_config_.has_spiral()) {
smoother_.reset(new SpiralReferenceLineSmoother(smoother_config_));
} else if (smoother_config_.has_discrete_points()) {
smoother_.reset(new DiscretePointsReferenceLineSmoother(smoother_config_));
} else {
ACHECK(false) << "unknown smoother config "
<< smoother_config_.DebugString();
}
Ps:apply_curvature_constraint_ =false

这分别是利用不同求解器实现了这个方法。如果考虑参考线的曲率约束,其优化问题是非线性的,可以使用ipopt非线性求解器求解(内点法),也可以使用osqp二次规划求解器来用SQP方法求解;如果不考虑曲率约束,则直接用osqp求解二次规划问题,Apollo默认使用FemPosDeviationSmoother::QpWithOsqp进行求解来减少计算量。

目标函数设计:

Apollo设计了三个代价函数,分别代表了平滑性、曲线总长度和参考点距离。大部分场景都是只考虑平滑性(平滑性权重默认设置为1e10,其他的权重设置为1)

weight_fem_pos_deviation: 1e10weight_ref_deviation: 1.0weight_path_length: 1.0

因此此处只考虑平滑性进行计算:

上述公式可以理解为:从中间那个点到第一个点的向量 和 从中间那个点到最后一个点的向量 的矢量和的模的平方。显然,如果这三个点在一条直线上,那么这个值最小;三个点组成的两个线段的夹角越小,即曲线越“弯”,这个值就越大。

示例代码(python) 用20个点模拟测试一下效果见图:

优化前后的轨迹点X,Y,kappa值

用途:

可对任意个X,Y坐标组成数组进行Fem Pos Deviation Smoother方法的平滑处理。


#!/usr/bin/python
# -*- coding: UTF-8 -*-
import osqp
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
#matplotlib widget
from scipy import sparse#add some data for test
x_array = [0.5,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0]
y_array = [0.1,0.3,0.2,0.4,0.3,-0.2,-0.1,0,0.5,0,0.1,0.3,0.2,0.4,0.3,-0.2,-0.1,0,0.5,0]
length = len(x_array)#weight , from config
weight_fem_pos_deviation_ = 1e10 #cost1 - x
# weight_path_length = 1          #cost2 - y
# weight_ref_deviation = 1        #cost3 - zP = np.zeros((length,length))
#set P matrix,from calculateKernel
#add cost1
P[0,0] = 1 * weight_fem_pos_deviation_
P[0,1] = -2 * weight_fem_pos_deviation_
P[1,1] = 5 * weight_fem_pos_deviation_
P[length - 1 , length - 1] = 1 * weight_fem_pos_deviation_
P[length - 2 , length - 1] = -2 * weight_fem_pos_deviation_
P[length - 2 , length - 2] = 5 * weight_fem_pos_deviation_for i in range(2 , length - 2):P[i , i] = 6 * weight_fem_pos_deviation_
for i in range(2 , length - 1):P[i - 1, i] = -4 * weight_fem_pos_deviation_
for i in range(2 , length):P[i - 2, i] = 1 * weight_fem_pos_deviation_with np.printoptions(precision=0):print(P)P = P / weight_fem_pos_deviation_
P = sparse.csc_matrix(P)#set q matrix , from calculateOffset
q = np.zeros(length)#set Bound(upper/lower bound) matrix , add constraints for x
#from CalculateAffineConstraint#In apollo , Bound is from road boundary,
#Config limit with (0.1,0.5) , Here I set a constant 0.2
bound = 0.2
A = np.zeros((length,length))
for i in range(length):A[i, i] = 1
A = sparse.csc_matrix(A)
lx = np.array(x_array) - bound
ux = np.array(x_array) + bound
ly = np.array(y_array) - bound
uy = np.array(y_array) + bound#solve
prob = osqp.OSQP()
prob.setup(P,q,A,lx,ux)
res = prob.solve()
opt_x = res.xprob.update(l=ly, u=uy)
res = prob.solve()
opt_y = res.x#plot x - y , opt_x - opt_y , lb - ubfig1 = plt.figure(dpi = 100 , figsize=(12, 8))
ax1_1 = fig1.add_subplot(2,1,1)ax1_1.plot(x_array,y_array , ".--", color = "grey", label="orig x-y")
ax1_1.plot(opt_x, opt_y,".-",label = "opt x-y")
# ax1_1.plot(x_array,ly,".--r",label = "bound")
# ax1_1.plot(x_array,uy,".--r")
ax1_1.legend()
ax1_1.grid(axis="y",ls='--')#计算kappa用来评价曲线
def calcKappa(x_array,y_array):s_array = []k_array = []if(len(x_array) != len(y_array)):return(s_array , k_array)length = len(x_array)temp_s = 0.0s_array.append(temp_s)for i in range(1 , length):temp_s += np.sqrt(np.square(y_array[i] - y_array[i - 1]) + np.square(x_array[i] - x_array[i - 1]))s_array.append(temp_s)xds,yds,xdds,ydds = [],[],[],[]for i in range(length):if i == 0:xds.append((x_array[i + 1] - x_array[i]) / (s_array[i + 1] - s_array[i]))yds.append((y_array[i + 1] - y_array[i]) / (s_array[i + 1] - s_array[i]))elif i == length - 1:xds.append((x_array[i] - x_array[i-1]) / (s_array[i] - s_array[i-1]))yds.append((y_array[i] - y_array[i-1]) / (s_array[i] - s_array[i-1]))else:xds.append((x_array[i+1] - x_array[i-1]) / (s_array[i+1] - s_array[i-1]))yds.append((y_array[i+1] - y_array[i-1]) / (s_array[i+1] - s_array[i-1]))for i in range(length):if i == 0:xdds.append((xds[i + 1] - xds[i]) / (s_array[i + 1] - s_array[i]))ydds.append((yds[i + 1] - yds[i]) / (s_array[i + 1] - s_array[i]))elif i == length - 1:xdds.append((xds[i] - xds[i-1]) / (s_array[i] - s_array[i-1]))ydds.append((yds[i] - yds[i-1]) / (s_array[i] - s_array[i-1]))else:xdds.append((xds[i+1] - xds[i-1]) / (s_array[i+1] - s_array[i-1]))ydds.append((yds[i+1] - yds[i-1]) / (s_array[i+1] - s_array[i-1]))for i in range(length):k_array.append((xds[i] * ydds[i] - yds[i] * xdds[i]) / (np.sqrt(xds[i] * xds[i] + yds[i] * yds[i]) * (xds[i] * xds[i] + yds[i] * yds[i]) + 1e-6));return(s_array,k_array)ax1_2 = fig1.add_subplot(2,1,2)
s_orig,k_orig = calcKappa(x_array,y_array)
s_opt ,k_opt = calcKappa(opt_x,opt_y)
ax1_2.plot(s_orig , k_orig , ".--", color = "grey", label="orig s-kappa")
ax1_2.plot(s_opt,k_opt,".-",label="opt s-kappa")
ax1_2.legend()
ax1_2.grid(axis="y",ls='--')
plt.show()

参考链接:

https://www.cnblogs.com/icathianrain/p/14407757.html

https://zhuanlan.zhihu.com/p/365371616

https://zhuanlan.zhihu.com/p/342740447

Apollo 参考线平滑方法Fem Pos Deviation Smoother相关推荐

  1. 无人驾驶算法——Baidu Apollo代码解析之ReferenceLine Smoother参考线平滑

    无人驾驶算法--Baidu Apollo代码解析之ReferenceLine Smoother参考线平滑 Apollo 参考线平滑类 reference_line_provider.cc 代价函数 c ...

  2. 百度Apollo代码阅读:参考线平滑FemPosDeviationSmoother

    在Apollo 5.0中,新增加了FemPosDeviationSmoother参考线平滑方法.在reference_line_provider.cc中可以看到,Apollo主要的参考线平滑类有三个: ...

  3. Apollo planning之参考线平滑算法

    Apollo studio 官网:Apollo开发者社区 (baidu.com) 星火计划2.0基础课:Apollo星火计划2.0_Apollo精品课 (baidu.com) 星火计划2.0专项课:A ...

  4. Apollo星火计划学习笔记——参考线平滑算法解析及实现(以U型弯道场景仿真调试为例)

    文章目录 1. Apollo参考线介绍 1.1 参考线的作用 1.2 导航规划的路线 1.3 为什么需要重新生成参考线 1.4 ReferenceLine数据结构 1.5 ReferencePoint ...

  5. 非参数统计中的核平滑方法/Kernel smoother

    Kernel Smoother   核函数Khλ(X0,X)K_{h_\lambda}(X_0,X)Khλ​​(X0​,X)定义为 Khλ(X0,X)=D(∣∣X−X0∣∣hλ(X0))K_{h_\l ...

  6. 2.参考线平滑算法解析及实现

    星火计划2.0基础课:https://apollo.baidu.com/community/online-course/2 星火计划2.0专项课:https://apollo.baidu.com/co ...

  7. 参考线平滑-QpSplineReferenceLineSmoother

    Apollo中提供了QpSplineReferenceLineSmoother,即分段五次多项式曲线平滑参考线方法.将其构造成二次规划问题形式,使用OSQP求解.OSQP求解的问题形式如下: m i ...

  8. Jelinek-Merer与Absolute discounting 平滑方法

    Jelinek-Merer Jelinek-Merer平滑方法的基本思想是利用低元n-gram模型对高元n-gram模型进行线性插值. PML(wi∣wi−1)=c(wi,wi−1)c(wi−1)P_ ...

  9. python 数据平滑_数据平滑方法的原理和应用

    一.简介 在实际的工程应用中,经常会遇到初始结果噪声太多的问题,比如信号强度抖动的太厉害,比如视频流中的bbox抖动的太厉害,比如光谱信号抖动的太厉害等等,这时候就需要一些简单的滑动平均算法.滑动平均 ...

最新文章

  1. 智能车竞赛中的人工智能
  2. java属于高级语言_以下哪种语言属于高级语言________________。A、JavaB、C++C、VisualBa...
  3. 计算机设备布局图,针对不同设备类型创建仪表板布局
  4. 菜鸟教程中Java语法(Java教程+Java面向对象)
  5. AGC002F - Leftmost Ball(dp,组合计数)
  6. 穿透、击穿、雪崩…Redis这么多问题,如何解决
  7. 网络资产管理系统_网络版固定资产管理系统具备哪些优势?
  8. typecho 全站ajax,Typecho全站启用HTTPS教程
  9. 【数据结构和算法笔记】插入排序(直接插入排序,折半插入排序)
  10. 阿里云容器服务Kubernetes之Jenkins X(2)-自动化CICD实践篇
  11. ASP 文件下载实例
  12. 项目进度管理表模板_IT项目进度管理—你能驾驭的项目节奏
  13. mysql多个数据库查询_如何跨多个数据库查询
  14. JAVA 实现银行卡归属地查询
  15. 信号处理常用matlab之数字滤波器及滤波函数
  16. php服务器搬迁失败原因
  17. 全国各地所有高校名单数据库 全国所有高校排名
  18. 上行下行带宽什么意思?代表了什么看完你就能懂
  19. 某公司要开发新游戏,请用面向对象的思想,设计游戏中的蛇怪和蜈蚣精
  20. pytorch项目报错:ImportError: no module named “cd“

热门文章

  1. android迷宫图像生成,Android - 绘制一个迷宫,以平滑的角色移动的画布
  2. 呕心沥血之飞冰(icejs)项目使用vue组件 -- vuera
  3. 开源的app后台开源框架汇总
  4. Smoke Loader、AZORult木马通过虚假海啸警报传播到了日本
  5. PHP 获取第一个汉字大写首字母
  6. 通通锁接口调用<Response [400]>报错及python示例代码
  7. Vue常用的组件库大全【前端工程师必备】【实时更新】【移动端、PC端(web端)、数据可视化组件库(数据大屏) 、动画组件库、3D组件库】
  8. c语言未定义main报错,C语言编译器的错误信息
  9. age estimation阅读整理(一)
  10. python打包成pyc文件发布_Python 使用pyinstaller将py文件发布成exe程序