31 #include <unordered_map> 39 namespace mcm = marti_common_msgs;
40 namespace mnm = marti_nav_msgs;
45 static void addItem(mcm::KeyValueArray &m,
const std::string &key,
const std::string &value)
47 m.items.emplace_back();
48 m.items.back().key = key;
49 m.items.back().value = value;
54 use_speed_from_accel_constant_(true),
55 max_lateral_accel_mss_(0.2),
56 curvature_filter_size_(20.0)
73 ROS_ERROR(
"Failed to load speed/curve parameter. Forcing lateral acceleration mode.");
79 ROS_INFO(
" %zu -- %f [1/m] vs %f [m/s]", i, pt.first, pt.second);
86 std::unordered_map<std::string, std::string> config_map;
87 for (
size_t i = 0; i < config.items.size(); ++i) {
88 config_map[config.items[i].key] = config.items[i].value;
91 if (config_map.count(
"curvature_filter_size")) {
94 config_map.erase(
"curvature_filter_size");
97 if (config_map.count(
"lateral_acceleration_mode")) {
99 boost::lexical_cast<
int>(config_map.at(
"lateral_acceleration_mode"));
100 ROS_INFO(
"Setting lateral acceleration mode to %s",
102 config_map.erase(
"lateral_acceleration_mode");
105 if (config_map.count(
"max_lateral_acceleration")) {
108 config_map.erase(
"max_lateral_acceleration");
111 if (config_map.count(
"curvature_vs_speed/interpolation_type")) {
112 std::string interp_type = config_map.at(
"curvature_vs_speed/interpolation_type");
113 if (interp_type ==
"zero_order_hold") {
115 ROS_INFO(
"Setting interpolation type to %s", interp_type.c_str());
116 }
else if (interp_type ==
"linear") {
118 ROS_INFO(
"Setting interpolation type to %s", interp_type.c_str());
120 ROS_ERROR(
"Ignoring invalid interpolation type '%s'.", interp_type.c_str());
122 config_map.erase(
"curvature_vs_speed/interpolation_type");
129 std::vector<double>
x;
130 std::vector<double>
y;
131 for (
size_t i = 0;
true; i++) {
133 snprintf(base_key,
sizeof(base_key),
"curvature_vs_speed/values/%zu", i);
134 const std::string x_key = std::string(base_key) +
"/0";
135 const std::string y_key = std::string(base_key) +
"/1";
137 if (config_map.count(x_key) && config_map.count(y_key)) {
138 x.push_back(boost::lexical_cast<double>(config_map.at(x_key)));
139 config_map.erase(x_key);
140 y.push_back(boost::lexical_cast<double>(config_map.at(y_key)));
141 config_map.erase(y_key);
151 ROS_INFO(
"Setting curvature_vs_speed curve: ");
153 for (
size_t i = 0; i < x.size(); i++) {
155 ROS_INFO(
" %zu -- %lf, %lf", i, x[i], y[i]);
160 for (
auto const &it : config_map) {
161 ROS_WARN(
"Ignoring unknown configuration value '%s'", it.first.c_str());
167 mcm::KeyValueArrayPtr
msg = boost::make_shared<mcm::KeyValueArray>();
170 addItem(config,
"curvature_filter_size",
172 addItem(config,
"lateral_acceleration_mode",
174 addItem(config,
"max_lateral_acceleration",
176 addItem(config,
"curvature_vs_speed/interpolation_type",
181 snprintf(base_key,
sizeof(base_key),
"curvature_vs_speed/values/%zu", i);
183 addItem(config, std::string(base_key) +
"/0",
185 addItem(config, std::string(base_key) +
"/1",
195 mnm::RoutePosition pos1;
196 pos1.id = route.
points[index].id();
200 mnm::RoutePosition pos0 = pos1;
201 pos0.distance -= filter_size;
204 mnm::RoutePosition pos2 = pos1;
205 pos2.distance += filter_size;
220 return ((T1-T0)/filter_size).
length();
226 double k = std::abs(curvature);
231 double max_speed = 1000.0;
236 return std::min(max_speed, std::sqrt(a/k));
244 mnm::RouteSpeedArray &speeds,
251 speeds.speeds.resize(route.
points.size());
253 for (
size_t i = 0; i < route.
points.size(); ++i) {
254 speeds.speeds[i].id = route.
points[i].id();
255 speeds.speeds[i].distance = 0.0;
264 origin_to_front_m_(2.0),
265 origin_to_rear_m_(1.0),
266 origin_to_left_m_(1.0),
267 origin_to_right_m_(1.0),
268 max_distance_m_(10.0),
269 min_distance_m_(1.0),
292 std::vector<ObstacleData> &obstacle_data,
294 const mnm::ObstacleArray &obstacles_msg)
296 obstacle_data.resize(obstacles_msg.obstacles.size());
297 for (
size_t i = 0; i < obstacle_data.size(); i++) {
298 const mnm::Obstacle &obs_msg = obstacles_msg.obstacles[i];
300 geometry_msgs::Pose pose = obs_msg.pose;
301 if (pose.orientation.x == 0.0 &&
302 pose.orientation.y == 0.0 &&
303 pose.orientation.z == 0.0 &&
304 pose.orientation.w == 0.0) {
305 pose.orientation.w = 1.0;
311 obstacle_data[i].center = g_route_from_obs*g_obs_from_local.
getOrigin();
312 obstacle_data[i].center.
setZ(0.0);
314 double max_radius = 0.0;
315 obstacle_data[i].polygon.resize(obs_msg.polygon.size());
316 for (
size_t j = 0; j < obs_msg.polygon.size(); j++) {
320 max_radius = std::max(max_radius, pt.
length());
321 obstacle_data[i].polygon[j] = g_route_from_obs*(g_obs_from_local*pt);
322 obstacle_data[i].polygon[j].setZ(0.0);
324 obstacle_data[i].radius = max_radius;
329 mnm::RouteSpeedArray &speeds,
330 std::vector<DistanceReport> &reports,
332 const mnm::RoutePosition &route_position,
333 const std::vector<ObstacleData> &obstacles,
341 car_r = std::max(car_r, local_fl.
length());
342 car_r = std::max(car_r, local_fr.
length());
343 car_r = std::max(car_r, local_br.
length());
344 car_r = std::max(car_r, local_bl.
length());
346 bool skip_point =
true;
348 for (
size_t route_index = 0; route_index < route.
points.size(); route_index++) {
352 if (point.
id() == route_position.id) {
362 double veh_r = car_r;
365 ROS_DEBUG(
"Speeds for obstacle found vehicle_width_override property");
369 if (veh_r >= width/2.0)
376 for (
const auto& obstacle: obstacles) {
378 const double d = v.
length() - veh_r - obstacle.radius;
386 double distance = std::numeric_limits<double>::max();
387 for (
size_t i = 1; i < obstacle.polygon.size(); i++) {
389 obstacle.polygon[i - 1],
393 if (dist < distance) {
396 obstacle.polygon[i - 1],
402 if (obstacle.polygon.size() > 1) {
404 obstacle.polygon.back(),
405 obstacle.polygon.front(),
408 if (dist < distance) {
411 obstacle.polygon.back(),
412 obstacle.polygon.front(),
425 if (distance > 0.0) {
432 reports.push_back(report);
438 speeds.speeds.emplace_back();
439 speeds.speeds.back().id = point.
id();
440 speeds.speeds.back().distance = 0.0;
441 speeds.speeds.back().speed = speed;
452 reports.push_back(report);
454 speeds.speeds.emplace_back();
455 speeds.speeds.back().id = point.
id();
457 speeds.speeds.back().speed = 0.0;
459 speeds.speeds.emplace_back();
460 speeds.speeds.back().id = point.
id();
462 speeds.speeds.back().speed = 0.0;
464 speeds.speeds.emplace_back();
465 speeds.speeds.back().id = point.
id();
466 speeds.speeds.back().distance = 0.0;
467 speeds.speeds.back().speed = 0.0;
bool appendPoint(double x, double y)
static void poseMsgToTF(const geometry_msgs::Pose &msg, Pose &bt)
std::string interpolationTypeString() const
static void pointMsgToTF(const geometry_msgs::Point &msg_v, Point &bt_v)
bool use_speed_from_accel_constant_
T getTypedProperty(const std::string &name) const
void loadFromRosParam(const ros::NodeHandle &pnh)
TFSIMD_FORCE_INLINE void setZ(tfScalar z)
bool interpolateRoutePosition(RoutePoint &point, const Route &route, const marti_nav_msgs::RoutePosition &position, bool allow_extrapolation)
void setInterpolationType(InterpolationType type)
void speedsForObstacles(marti_nav_msgs::RouteSpeedArray &speeds, std::vector< DistanceReport > &reports, const Route &route, const marti_nav_msgs::RoutePosition &route_position, const std::vector< ObstacleData > &obstacles, const SpeedForObstaclesParameters ¶meters)
void readToConfig(marti_common_msgs::KeyValueArray &config) const
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const
double eval(double x) const
TFSIMD_FORCE_INLINE const tfScalar & y() const
void loadFromRosParam(const ros::NodeHandle &pnh)
double curvature_filter_size_
static double maxSpeedForCurvature(double curvature, const SpeedForCurvatureParameters ¶ms)
TFSIMD_FORCE_INLINE Vector3 normalized() const
tf::Vector3 vehicle_point
static void param(const ros::NodeHandle &nh, const std::string &name, int &variable, const int default_value)
#define ROS_WARN_THROTTLE(period,...)
SpeedForObstaclesParameters()
static double estimateCurvature(const Route &route, const size_t index, double filter_size)
tf::Vector3 ProjectToLineSegment(const tf::Vector3 &line_start, const tf::Vector3 &line_end, const tf::Vector3 &point)
std::pair< double, double > getPoint(size_t index) const
TFSIMD_FORCE_INLINE const tfScalar & x() const
bool hasProperty(const std::string &name) const
double max_lateral_accel_mss_
Maximum lateral acceleration in accel mode in m/s^2.
std::vector< RoutePoint > points
const std::string & id() const
void speedsForCurvature(marti_nav_msgs::RouteSpeedArray &speeds, const Route &route, const SpeedForCurvatureParameters ¶meters)
double origin_to_right_m_
tf::Vector3 obstacle_point
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
double origin_to_front_m_
double DistanceFromLineSegment(const tf::Vector3 &line_start, const tf::Vector3 &line_end, const tf::Vector3 &point)
void generateObstacleData(std::vector< ObstacleData > &obstacle_data, const swri_transform_util::Transform g_route_from_obs, const marti_nav_msgs::ObstacleArray &obstacles_msg)
const tf::Vector3 & position() const
SpeedForCurvatureParameters()
bool readFromParameter(const ros::NodeHandle &node_handle, const std::string ¶m_name, bool error_if_missing)
void loadFromConfig(const marti_common_msgs::KeyValueArray &config)
TFSIMD_FORCE_INLINE tfScalar length() const
static void addItem(mcm::KeyValueArray &m, const std::string &key, const std::string &value)
swri_math_util::Interpolation1D speed_curve_