edge_velocity.h
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2016,
6  * TU Dortmund - Institute of Control Theory and Systems Engineering.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the institute nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * Notes:
37  * The following class is derived from a class defined by the
38  * g2o-framework. g2o is licensed under the terms of the BSD License.
39  * Refer to the base class source for detailed licensing information.
40  *
41  * Author: Christoph Rösmann
42  *********************************************************************/
43 
44 #ifndef EDGE_VELOCITY_H
45 #define EDGE_VELOCITY_H
46 
52 
53 
54 #include <iostream>
55 
56 namespace teb_local_planner
57 {
58 
59 
75 class EdgeVelocity : public BaseTebMultiEdge<2, double>
76 {
77 public:
78 
83  {
84  this->resize(3); // Since we derive from a g2o::BaseMultiEdge, set the desired number of vertices
85  }
86 
90  void computeError()
91  {
92  ROS_ASSERT_MSG(cfg_, "You must call setTebConfig on EdgeVelocity()");
93  const VertexPose* conf1 = static_cast<const VertexPose*>(_vertices[0]);
94  const VertexPose* conf2 = static_cast<const VertexPose*>(_vertices[1]);
95  const VertexTimeDiff* deltaT = static_cast<const VertexTimeDiff*>(_vertices[2]);
96 
97  const Eigen::Vector2d deltaS = conf2->estimate().position() - conf1->estimate().position();
98 
99  double dist = deltaS.norm();
100  const double angle_diff = g2o::normalize_theta(conf2->theta() - conf1->theta());
101  if (cfg_->trajectory.exact_arc_length && angle_diff != 0)
102  {
103  double radius = dist/(2*sin(angle_diff/2));
104  dist = fabs( angle_diff * radius ); // actual arg length!
105  }
106  double vel = dist / deltaT->estimate();
107 
108 // vel *= g2o::sign(deltaS[0]*cos(conf1->theta()) + deltaS[1]*sin(conf1->theta())); // consider direction
109  vel *= fast_sigmoid( 100 * (deltaS.x()*cos(conf1->theta()) + deltaS.y()*sin(conf1->theta())) ); // consider direction
110 
111  const double omega = angle_diff / deltaT->estimate();
112 
115 
116  ROS_ASSERT_MSG(std::isfinite(_error[0]), "EdgeVelocity::computeError() _error[0]=%f _error[1]=%f\n",_error[0],_error[1]);
117  }
118 
119 #ifdef USE_ANALYTIC_JACOBI
120 #if 0 //TODO the hardcoded jacobian does not include the changing direction (just the absolute value)
121  // Change accordingly...
122 
126  void linearizeOplus()
127  {
128  ROS_ASSERT_MSG(cfg_, "You must call setTebConfig on EdgeVelocity()");
129  const VertexPose* conf1 = static_cast<const VertexPose*>(_vertices[0]);
130  const VertexPose* conf2 = static_cast<const VertexPose*>(_vertices[1]);
131  const VertexTimeDiff* deltaT = static_cast<const VertexTimeDiff*>(_vertices[2]);
132 
133  Eigen::Vector2d deltaS = conf2->position() - conf1->position();
134  double dist = deltaS.norm();
135  double aux1 = dist*deltaT->estimate();
136  double aux2 = 1/deltaT->estimate();
137 
138  double vel = dist * aux2;
139  double omega = g2o::normalize_theta(conf2->theta() - conf1->theta()) * aux2;
140 
143 
144  _jacobianOplus[0].resize(2,3); // conf1
145  _jacobianOplus[1].resize(2,3); // conf2
146  _jacobianOplus[2].resize(2,1); // deltaT
147 
148 // if (aux1==0) aux1=1e-6;
149 // if (aux2==0) aux2=1e-6;
150 
151  if (dev_border_vel!=0)
152  {
153  double aux3 = dev_border_vel / aux1;
154  _jacobianOplus[0](0,0) = -deltaS[0] * aux3; // vel x1
155  _jacobianOplus[0](0,1) = -deltaS[1] * aux3; // vel y1
156  _jacobianOplus[1](0,0) = deltaS[0] * aux3; // vel x2
157  _jacobianOplus[1](0,1) = deltaS[1] * aux3; // vel y2
158  _jacobianOplus[2](0,0) = -vel * aux2 * dev_border_vel; // vel deltaT
159  }
160  else
161  {
162  _jacobianOplus[0](0,0) = 0; // vel x1
163  _jacobianOplus[0](0,1) = 0; // vel y1
164  _jacobianOplus[1](0,0) = 0; // vel x2
165  _jacobianOplus[1](0,1) = 0; // vel y2
166  _jacobianOplus[2](0,0) = 0; // vel deltaT
167  }
168 
169  if (dev_border_omega!=0)
170  {
171  double aux4 = aux2 * dev_border_omega;
172  _jacobianOplus[2](1,0) = -omega * aux4; // omega deltaT
173  _jacobianOplus[0](1,2) = -aux4; // omega angle1
174  _jacobianOplus[1](1,2) = aux4; // omega angle2
175  }
176  else
177  {
178  _jacobianOplus[2](1,0) = 0; // omega deltaT
179  _jacobianOplus[0](1,2) = 0; // omega angle1
180  _jacobianOplus[1](1,2) = 0; // omega angle2
181  }
182 
183  _jacobianOplus[0](1,0) = 0; // omega x1
184  _jacobianOplus[0](1,1) = 0; // omega y1
185  _jacobianOplus[1](1,0) = 0; // omega x2
186  _jacobianOplus[1](1,1) = 0; // omega y2
187  _jacobianOplus[0](0,2) = 0; // vel angle1
188  _jacobianOplus[1](0,2) = 0; // vel angle2
189  }
190 #endif
191 #endif
192 
193 
194 public:
195 
196  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
197 
198 };
199 
200 
201 
202 
203 
204 
221 class EdgeVelocityHolonomic : public BaseTebMultiEdge<3, double>
222 {
223 public:
224 
229  {
230  this->resize(3); // Since we derive from a g2o::BaseMultiEdge, set the desired number of vertices
231  }
232 
237  {
238  ROS_ASSERT_MSG(cfg_, "You must call setTebConfig on EdgeVelocityHolonomic()");
239  const VertexPose* conf1 = static_cast<const VertexPose*>(_vertices[0]);
240  const VertexPose* conf2 = static_cast<const VertexPose*>(_vertices[1]);
241  const VertexTimeDiff* deltaT = static_cast<const VertexTimeDiff*>(_vertices[2]);
242  Eigen::Vector2d deltaS = conf2->position() - conf1->position();
243 
244  double cos_theta1 = std::cos(conf1->theta());
245  double sin_theta1 = std::sin(conf1->theta());
246 
247  // transform conf2 into current robot frame conf1 (inverse 2d rotation matrix)
248  double r_dx = cos_theta1*deltaS.x() + sin_theta1*deltaS.y();
249  double r_dy = -sin_theta1*deltaS.x() + cos_theta1*deltaS.y();
250 
251  double vx = r_dx / deltaT->estimate();
252  double vy = r_dy / deltaT->estimate();
253  double omega = g2o::normalize_theta(conf2->theta() - conf1->theta()) / deltaT->estimate();
254 
256  _error[1] = penaltyBoundToInterval(vy, cfg_->robot.max_vel_y, 0.0); // we do not apply the penalty epsilon here, since the velocity could be close to zero
258 
259  ROS_ASSERT_MSG(std::isfinite(_error[0]) && std::isfinite(_error[1]) && std::isfinite(_error[2]),
260  "EdgeVelocityHolonomic::computeError() _error[0]=%f _error[1]=%f _error[2]=%f\n",_error[0],_error[1],_error[2]);
261  }
262 
263 
264 public:
265 
266  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
267 
268 };
269 
270 
271 } // end namespace
272 
273 #endif
double max_vel_y
Maximum strafing velocity of the robot (should be zero for non-holonomic robots!) ...
Definition: teb_config.h:92
double penaltyBoundToInterval(const double &var, const double &a, const double &epsilon)
Linear penalty function for bounding var to the interval .
Definition: penalties.h:57
void computeError()
Actual cost function.
struct teb_local_planner::TebConfig::Robot robot
Robot related parameters.
Edge defining the cost function for limiting the translational and rotational velocity.
Definition: edge_velocity.h:75
struct teb_local_planner::TebConfig::Trajectory trajectory
Trajectory related parameters.
double fast_sigmoid(double x)
Calculate a fast approximation of a sigmoid function.
Definition: misc.h:95
void computeError()
Actual cost function.
Definition: edge_velocity.h:90
Edge defining the cost function for limiting the translational and rotational velocity according to x...
double & theta()
Access the orientation part (yaw angle) of the pose.
Definition: vertex_pose.h:178
Base edge connecting two vertices in the TEB optimization problem.
#define ROS_ASSERT_MSG(cond,...)
double max_vel_theta
Maximum angular velocity of the robot.
Definition: teb_config.h:93
double penaltyBoundToIntervalDerivative(const double &var, const double &a, const double &epsilon)
Derivative of the linear penalty function for bounding var to the interval .
Definition: penalties.h:127
double penalty_epsilon
Add a small safety margin to penalty functions for hard-constraint approximations.
Definition: teb_config.h:140
bool exact_arc_length
If true, the planner uses the exact arc length in velocity, acceleration and turning rate computation...
Definition: teb_config.h:81
EdgeVelocity()
Construct edge.
Definition: edge_velocity.h:82
Eigen::Vector2d & position()
Access the 2D position part.
Definition: vertex_pose.h:141
const TebConfig * cfg_
Store TebConfig class for parameters.
This class stores and wraps a SE2 pose (position and orientation) into a vertex that can be optimized...
Definition: vertex_pose.h:63
double max_vel_x_backwards
Maximum translational velocity of the robot for driving backwards.
Definition: teb_config.h:91
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
struct teb_local_planner::TebConfig::Optimization optim
Optimization related parameters.
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
double max_vel_x
Maximum translational velocity of the robot.
Definition: teb_config.h:90
This class stores and wraps a time difference into a vertex that can be optimized via g2o...


teb_local_planner
Author(s): Christoph Rösmann
autogenerated on Wed Jun 5 2019 19:25:10