速度和加速度约束的源码
source link: https://charon-cheung.github.io/2022/08/26/%E8%B7%AF%E5%BE%84%E8%A7%84%E5%88%92/TEB%E7%AE%97%E6%B3%95/%E9%80%9F%E5%BA%A6%E5%92%8C%E5%8A%A0%E9%80%9F%E5%BA%A6%E7%BA%A6%E6%9D%9F%E7%9A%84%E6%BA%90%E7%A0%81/#%E8%B5%B7%E7%82%B9%E7%9A%84%E5%8A%A0%E9%80%9F%E5%BA%A6%E7%BA%A6%E6%9D%9F
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
速度和加速度约束的源码 | 沉默杀手
所有约束在teb_local_planner\include\teb_local_planner\g2o_types
,都是头文件。
最小化的函数是 penaltyInterval([v,omega]T)⋅weightpenaltyInterval([v,omega]T)⋅weight
penaltyInterval
表示惩罚函数,见penaltyBoundToInterval()
函数,它只用于速度约束、加速度约束和edge_velocity_obstacle_ratio
errorcosterrorcost 向量的维度是2,第一个元素代表线速度,第二个是角速度。
调用:TebOptimalPlanner::AddEdgesVelocity
和 setTebConfig()
class EdgeVelocity : public BaseTebMultiEdge<2, double>
{
public:
EdgeVelocity()
{
this->resize(3); // from a g2o::BaseMultiEdge, set the desired number of vertices
}
// 代价函数
void computeError()
{
ROS_ASSERT_MSG(cfg_, "You must call setTebConfig on EdgeVelocity()");
const VertexPose* conf1 = static_cast<const VertexPose*>(_vertices[0]);
const VertexPose* conf2 = static_cast<const VertexPose*>(_vertices[1]);
const VertexTimeDiff* deltaT = static_cast<const VertexTimeDiff*>(_vertices[2]);
// 两点的向量差
const Eigen::Vector2d deltaS = conf2->estimate().position() - conf1->estimate().position();
double dist = deltaS.norm();
const double angle_diff = g2o::normalize_theta(conf2->theta() - conf1->theta());
// 使用实际弧长,而不是两点的直线距离
if (cfg_->trajectory.exact_arc_length && angle_diff != 0)
{
double radius = dist/(2*sin(angle_diff/2));
dist = fabs( angle_diff * radius ); // actual arg length!
}
double vel = dist / deltaT->estimate(); // 线速度
// fast_sigmoid函数是保证速度连续可微
// vel *= g2o::sign(deltaS[0]*cos(conf1->theta()) + deltaS[1]*sin(conf1->theta())); // consider direction
vel *= fast_sigmoid( 100 * (deltaS.x()*cos(conf1->theta()) + deltaS.y()*sin(conf1->theta())) ); // consider direction
const double omega = angle_diff / deltaT->estimate(); // 角速度
// 线速度需要限制在最大和最大倒退的范围内
_error[0] = penaltyBoundToInterval(vel, -cfg_->robot.max_vel_x_backwards, cfg_->robot.max_vel_x, cfg_->optim.penalty_epsilon);
// 角速度只需限制在最大内
_error[1] = penaltyBoundToInterval(omega, cfg_->robot.max_vel_theta, cfg_->optim.penalty_epsilon);
ROS_ASSERT_MSG(std::isfinite(_error[0]), "EdgeVelocity::computeError() _error[0]=%f _error[1]=%f\n",_error[0],_error[1]);
}
人工智能开发中很少用到不是0就是1的阶跃函数,而是用更为平滑过渡的sigmoid
的函数,在深度学习里用的很多。这里的fast_sigmoid
函数是保证速度连续可微,很有借鉴意义。
Rösmann还使用了sign/sigmoid
函数决定当前的运动方向。
加速度约束
默认为5元边约束。 但是包含3个类:EdgeAcceleration
, EdgeAccelerationStart
, EdgeAccelerationGoal
,后两个为3元边
errorcosterrorcost 向量的维度是2,第一个元素代表线加速度,第二个是角加速度。EdgeAccelerationStart()
and EdgeAccelerationGoal()
用于边界值
加速度约束和速度约束类似,不过变成两段圆弧和角度差、两个时间差、两个线速度和角速度。两个线速度的差除以两个时间差之和就是加速度。
double vel1 = dist1 / dt1->dt();
double vel2 = dist2 / dt2->dt();
const double acc_lin = (vel2 - vel1)*2 / ( dt1->dt() + dt2->dt() );
_error[0] = penaltyBoundToInterval(acc_lin,cfg_->robot.acc_lim_x, cfg_->optim.penalty_epsilon);
const double omega1 = angle_diff1 / dt1->dt();
const double omega2 = angle_diff2 / dt2->dt();
const double acc_rot = (omega2 - omega1)*2 / ( dt1->dt() + dt2->dt() );
_error[1] = penaltyBoundToInterval(acc_rot,cfg_->robot.acc_lim_theta, cfg_->optim.penalty_epsilon);
起点的加速度约束
注意:起点加速度约束和终点加速度约束都是3元边。
对于起点的加速度约束,源码有以下变化:
void setInitialVelocity(const geometry_msgs::Twist& vel_start)
{
_measurement = &vel_start;
}
ROS_ASSERT_MSG(cfg_ && _measurement,
"You must call setTebConfig() and setInitialVelocity() on EdgeAccelerationStart()");
vel1 = _measurement->linear.x;
omega1 = _measurement->angular.z;
其他全一样,对于终点的加速度约束,则是vel2
和omega2
换成了_measurement
的成员。那么这个_measurement
从何而来?
在TebOptimalPlanner::plan
里有一段:
if (start_vel)
setVelocityStart(*start_vel);
if (free_goal_vel)
setVelocityGoalFree();
else
vel_goal_.first = true;
setVelocityStart
给起始速度赋值:
// std::pair<bool, geometry_msgs::Twist> vel_start_;
// 注意vel_start_ 和 vel_start 不同
void TebOptimalPlanner::setVelocityStart(const geometry_msgs::Twist& vel_start)
{
vel_start_.first = true;
vel_start_.second.linear.x = vel_start.linear.x;
vel_start_.second.linear.y = vel_start.linear.y;
vel_start_.second.angular.z = vel_start.angular.z;
}
然后到了AddEdgesAcceleration
里添加起始加速度约束,才用到vel_start_
if (vel_start_.first)
{
EdgeAccelerationStart* acceleration_edge = new EdgeAccelerationStart;
acceleration_edge->setVertex(0,teb_.PoseVertex(0));
acceleration_edge->setVertex(1,teb_.PoseVertex(1));
acceleration_edge->setVertex(2,teb_.TimeDiffVertex(0));
// 这里就是上面的 setInitialVelocity, _measurement 就是 vel_start_.second
acceleration_edge->setInitialVelocity(vel_start_.second);
acceleration_edge->setInformation(information);
acceleration_edge->setTebConfig(*cfg_);
optimizer_->addEdge(acceleration_edge);
}
AddEdgesAcceleration
然后添加普通的加速度约束,再就是终点的加速度约束,这里就奇怪了,相应的setVelocityGoal
函数没有调用的地方,这里是vel_goal_.second
唯一赋值的地方。即使free_goal_vel
为false,也没有赋值,意思是终点的速度为0?
Recommend
-
47
直播答题效仿了美国的HQ Trivia,国内一般认为其是《开心辞典》和《贫民窟里的百万富翁》的翻版,同时由于嫁接在直播的内容生态上,中国的直播答题成为了脱口秀+知识变现的营销组合体。
-
38
5G加速度 配套需同步(互联网前沿追踪) 日前,国际移动通信标准化组织3GPP,正式批准确立第五代移动通信技术标准(5G NR)独立组网功能,第一阶...
-
33
新浪科技讯北京时间7月17日消息,据国外媒体报道,此刻的你是不是正坐着不动?错,大错特错。事实上,你不仅身处一个旋转的行星,而且正在以每秒将近30公里的速度围绕一颗恒星运动;而观测显示,身处银河系的你正在以超过每秒600公里的速度穿过太空。
-
14
周四美股收盘,小牛电动涨10.38%,盘后再涨14.15%,现报16.38美元,创上市以来股价新高。值得一提的是,今年年内小牛电动股价累计涨幅已达68.23...
-
10
优税猫“重生·加速度”全国税务规划论坛落幕 - 精选 - 商界网 | 商界APP-专注于商人-企业以及商业思维 优税猫“重生·加速度”全国税务规划论坛落幕 ...
-
8
企业微信的加速度 本文来自微信公众号“牛透社”(ID:Neuters)。
-
6
编辑导语:品牌势能指的是消费者认知价值和品牌初始价值之间的正向高度差,它能增强用户对品牌的关注并促进品牌消费。本文作者从是什么、有什么作用和怎么做三个方面对品牌势能展开了梳理说明,与大家分享。
-
4
本文将开始讲述动画编程的部分,会从基本的运动属性开始:速度、向量和加速度 速度向量指某个方向上的速度。这里包含速度的值和方向(既有大小,又有方向)。 任何一个速度向量又可以被分解为 x 方向和 y 方向。 接下来的示例中,...
-
5
加速度约束和雅格比矩阵的推导 | 沉默杀手加速度约束和雅格比矩阵的推导 2023-03-04|
-
1
0315 - 加速度比速度重要 ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK