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 std::vector<ObstacleData> &obstacle_data,
331 const mnm::TrackedObjectArray &obstacles_msg)
333 obstacle_data.resize(obstacles_msg.objects.size());
334 for (
size_t i = 0; i < obstacle_data.size(); i++) {
335 const mnm::TrackedObject &obs_msg = obstacles_msg.objects[i];
337 geometry_msgs::Pose pose = obs_msg.pose.pose;
338 if (pose.orientation.x == 0.0 &&
339 pose.orientation.y == 0.0 &&
340 pose.orientation.z == 0.0 &&
341 pose.orientation.w == 0.0) {
342 pose.orientation.w = 1.0;
348 obstacle_data[i].center = g_route_from_obs*g_obs_from_local.
getOrigin();
349 obstacle_data[i].center.setZ(0.0);
351 double max_radius = 0.0;
352 obstacle_data[i].polygon.resize(obs_msg.polygon.size());
353 for (
size_t j = 0; j < obs_msg.polygon.size(); j++) {
357 max_radius = std::max(max_radius, pt.length());
358 obstacle_data[i].polygon[j] = g_route_from_obs*(g_obs_from_local*pt);
359 obstacle_data[i].polygon[j].setZ(0.0);
361 obstacle_data[i].radius = max_radius;
366 mnm::RouteSpeedArray &speeds,
367 std::vector<DistanceReport> &reports,
369 const mnm::RoutePosition &route_position,
370 const std::vector<ObstacleData> &obstacles,
378 car_r = std::max(car_r, local_fl.length());
379 car_r = std::max(car_r, local_fr.length());
380 car_r = std::max(car_r, local_br.length());
381 car_r = std::max(car_r, local_bl.length());
383 bool skip_point =
true;
385 for (
size_t route_index = 0; route_index < route.
points.size(); route_index++) {
389 if (point.
id() == route_position.id) {
399 double veh_r = car_r;
402 ROS_DEBUG(
"Speeds for obstacle found vehicle_width_override property");
406 if (veh_r >= width/2.0)
413 for (
const auto& obstacle: obstacles) {
414 const tf::Vector3 v = obstacle.center - point.
position();
415 const double d = v.length() - veh_r - obstacle.radius;
421 tf::Vector3 closest_point = obstacle.center;
423 double distance = std::numeric_limits<double>::max();
424 for (
size_t i = 1; i < obstacle.polygon.size(); i++) {
426 obstacle.polygon[i - 1],
430 if (dist < distance) {
433 obstacle.polygon[i - 1],
439 if (obstacle.polygon.size() > 1) {
441 obstacle.polygon.back(),
442 obstacle.polygon.front(),
445 if (dist < distance) {
448 obstacle.polygon.back(),
449 obstacle.polygon.front(),
462 if (distance > 0.0) {
469 reports.push_back(report);
475 speeds.speeds.emplace_back();
476 speeds.speeds.back().id = point.
id();
477 speeds.speeds.back().distance = 0.0;
478 speeds.speeds.back().speed = speed;
489 reports.push_back(report);
491 speeds.speeds.emplace_back();
492 speeds.speeds.back().id = point.
id();
494 speeds.speeds.back().speed = 0.0;
496 speeds.speeds.emplace_back();
497 speeds.speeds.back().id = point.
id();
499 speeds.speeds.back().speed = 0.0;
501 speeds.speeds.emplace_back();
502 speeds.speeds.back().id = point.
id();
503 speeds.speeds.back().distance = 0.0;
504 speeds.speeds.back().speed = 0.0;