26 return (v * v) / (2.0 * a);
37 return (std::pow(free_flow_speed, 2) - std::pow(current_speed, 2))/(2 * max_accel) + (std::pow(departure_speed, 2) - std::pow(free_flow_speed, 2))/(2* max_decel);
42 if (current_speed <= departure_speed +
epsilon_)
44 return (std::pow(departure_speed, 2) - std::pow(current_speed, 2))/(2 * max_accel);
48 return (std::pow(departure_speed, 2) - std::pow(current_speed, 2))/(2 * max_decel);
55 auto start_of_tbd_time = rclcpp::Time((lanelet::time::toSec(signal->recorded_time_stamps.back().first) +
EPSILON) * 1e9);
56 if (earliest_entry_time > start_of_tbd_time)
58 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Not enough signals are available to check for EET, so returning EET at: " <<
std::to_string(earliest_entry_time.seconds()));
59 return earliest_entry_time;
62 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"No valid green entry time found, so returning start of TBD at: " <<
std::to_string(start_of_tbd_time.seconds()));
63 return start_of_tbd_time;
68 boost::posix_time::time_duration g = lanelet::time::durationFromSec(minimum_required_green_time);
69 boost::posix_time::ptime t = lanelet::time::timeFromSec(current_time.seconds());
70 boost::posix_time::ptime eet = lanelet::time::timeFromSec(earliest_entry_time.seconds());
73 bool has_green_signal =
false;
74 for (
auto pair : signal->recorded_time_stamps)
76 if (pair.second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED &&
79 has_green_signal =
true;
84 if (!has_green_signal)
89 auto curr_pair = signal->predictState(t);
91 throw std::invalid_argument(
"Traffic signal with id:" +
std::to_string(signal->id()) +
", does not have any recorded time stamps!");
93 boost::posix_time::time_duration theta = curr_pair.get().first - t;
94 auto p = curr_pair.get().second;
95 while ( 0.0 < g.total_milliseconds() || p != lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
97 if ( p == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
103 g = boost::posix_time::seconds(0);
109 curr_pair = signal->predictState(t + boost::posix_time::milliseconds(20));
110 p = curr_pair.get().second;
111 theta = curr_pair.get().first - t;
117 curr_pair = signal->predictState(t + boost::posix_time::milliseconds(20));
118 p = curr_pair.get().second;
119 theta = curr_pair.get().first - t;
125 double cycle_duration = signal->fixed_cycle_duration.total_milliseconds()/1000.0;
126 if (cycle_duration < 0.001)
127 cycle_duration = lanelet::time::toSec(signal->recorded_time_stamps.back().first) - lanelet::time::toSec(signal->recorded_start_time_stamps.front());
129 t = t + lanelet::time::durationFromSec(std::floor((eet - t).total_milliseconds()/1000.0/cycle_duration) * cycle_duration);
130 curr_pair = signal->predictState(t + boost::posix_time::milliseconds(20));
131 p = curr_pair.get().second;
132 theta = curr_pair.get().first - t;
133 while ( t < eet || p != lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
135 if ( p == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED && eet - t < theta)
138 theta = theta - (eet - t);
143 curr_pair = signal->predictState(t + boost::posix_time::milliseconds(20));
144 p = curr_pair.get().second;
145 theta = curr_pair.get().first - t;
148 if (t != lanelet::time::timeFromSec(lanelet::time::INFINITY_END_TIME_FOR_NOT_ENOUGH_STATES))
155 return rclcpp::Time(lanelet::time::toSec(t) * 1e9);
161 double accel_ratio = max_accel / max_decel;
162 double remaining_time = time_remaining_at_free_flow - full_cycle_duration / 2;
163 double inflection_speed = (max_accel * remaining_time - accel_ratio * departure_speed + current_speed)/ (1 - accel_ratio);
164 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"ENTER TRAJ CALC: time_remaining_at_free_flow: " << time_remaining_at_free_flow <<
", full_cycle_duration: " << full_cycle_duration <<
", inflection_speed: " << inflection_speed);
166 if (remaining_time < 0)
169 if (inflection_speed > 0 && inflection_speed <= speed_limit + epsilon_ && inflection_speed >= departure_speed -
epsilon_)
173 double d = (std::pow(inflection_speed, 2) - std::pow (current_speed, 2)) / (2 * max_accel) + (std::pow(departure_speed, 2) - std::pow(inflection_speed, 2)) / (2 * max_decel);
174 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"calculated distance WITHOUT cruising: " << d);
181 double decel_time = (current_speed - speed_limit) / max_decel;
182 double accel_time = (speed_limit - current_speed) / max_accel;
183 double cruising_time = remaining_time - decel_time - accel_time;
184 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"decel_time: " << decel_time <<
", accel_time: " << accel_time <<
", cruising_time: " << cruising_time);
185 double d = (std::pow(speed_limit, 2) - std::pow (current_speed, 2)) / (2 * max_accel) + (std::pow(departure_speed, 2) - std::pow(speed_limit, 2)) / (2 * max_decel) + cruising_time * speed_limit;
186 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"calculated distance with cruising: " << d <<
", accel_seg: " << (std::pow(speed_limit, 2) - std::pow (current_speed, 2)) / (2 * max_accel) <<
187 ", cruising: " << + cruising_time * speed_limit <<
", decel_seg:" << (std::pow(departure_speed, 2) - std::pow(speed_limit, 2)) / (2 * max_decel));
194 double x = remaining_distance;
199 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"x: " <<
x <<
", x2: " << x2 <<
", x1: " << x1 <<
", v_hat: " << v_hat);
203 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Detected that v_hat is smaller than allowed!!!: " << v_hat);
207 if (v_hat >= free_flow_speed +
epsilon_)
209 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Detected that v_hat is Bigger than allowed!!!: " << v_hat);
210 v_hat = free_flow_speed;
213 rclcpp::Duration t_accel(0,0);
214 if ( x < x2 && current_speed > departure_speed)
216 t_accel = rclcpp::Duration(0.0);
220 t_accel = rclcpp::Duration(std::max((v_hat - current_speed) / max_accel, 0.0) * 1e9);
222 rclcpp::Duration t_decel(0,0);
223 if (
x < x2 && current_speed < departure_speed)
225 t_decel = rclcpp::Duration(0.0);
231 t_decel = rclcpp::Duration(std::max((v_hat - current_speed) / max_decel, 0.0) * 1e9);
236 t_decel = rclcpp::Duration(std::max((departure_speed - v_hat) / max_decel, 0.0) * 1e9);
240 rclcpp::Duration t_cruise(0,0);
243 t_cruise = rclcpp::Duration(std::max((
x - x1)/v_hat, 0.0) * 1e9);
247 t_cruise = rclcpp::Duration(0.0);
249 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"t_accel: " << t_accel.seconds() <<
", t_cruise: " << t_cruise.seconds() <<
", t_decel: " << t_decel.seconds());
250 return t_accel + t_cruise + t_decel;
256 rclcpp::Time nearest_green_entry_time = rclcpp::Time(0);
257 bool is_entry_time_within_green_or_tbd =
false;
263 is_entry_time_within_green_or_tbd =
true;
265 if (!nearest_green_entry_time_optional)
267 nearest_green_entry_time =
get_eet_or_tbd(earliest_entry_time, traffic_light);
272 nearest_green_entry_time = nearest_green_entry_time_optional.value() + rclcpp::Duration(
EPSILON * 1e9);
277 nearest_green_entry_time = rclcpp::Time(std::max(earliest_entry_time.seconds(), (
scheduled_enter_time_)/1000.0) * 1e9) + rclcpp::Duration(
EPSILON * 1e9);
283 for (
auto pair : traffic_light->recorded_time_stamps)
285 if (lanelet::time::timeFromSec(nearest_green_entry_time.seconds()) < pair.first)
287 if (pair.second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
289 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"ET is inside the GREEN phase! where starting time: " <<
std::to_string(lanelet::time::toSec(traffic_light->recorded_start_time_stamps[
i]))
290 <<
", ending time of that green signal is: " <<
std::to_string(lanelet::time::toSec(pair.first)));
291 is_entry_time_within_green_or_tbd =
true;
295 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Vehicle should plan cruise and stop as ET is inside the RED or YELLOW phase! where starting time: " <<
std::to_string(lanelet::time::toSec(traffic_light->recorded_start_time_stamps[
i]))
296 <<
", ending time of that green signal is: " <<
std::to_string(lanelet::time::toSec(pair.first)));
297 is_entry_time_within_green_or_tbd =
false;
308 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"ET is inside TBD phase! where starting time: " <<
std::to_string(lanelet::time::toSec(traffic_light->recorded_time_stamps.back().first)));
309 is_entry_time_within_green_or_tbd =
true;
313 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"nearest_green_entry_time: " << nearest_green_entry_time.get_clock_type());
314 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"current_state.stamp: " << current_state.
stamp.get_clock_type());
316 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"nearest_green_entry_time: " <<
std::to_string(nearest_green_entry_time.seconds()) <<
", with : " <<
std::to_string((nearest_green_entry_time - current_state.
stamp).seconds()) <<
" seconds left at: " <<
std::to_string(current_state.
stamp.seconds()));
323 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"After accounting for cached - nearest_green_entry_time: " <<
std::to_string(nearest_green_entry_time.seconds()) <<
", with : " <<
std::to_string((nearest_green_entry_time - current_state.
stamp).seconds()) <<
" seconds left at: " <<
std::to_string(current_state.
stamp.seconds()));
327 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Applying green_light_buffer for the first time and caching! nearest_green_entry_time (without buffer):" <<
std::to_string(nearest_green_entry_time.seconds()) <<
", and earliest_entry_time: " <<
std::to_string(earliest_entry_time.seconds()));
331 rclcpp::Time early_arrival_time_green_et =
334 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"early_arrival_time_green_et: " <<
std::to_string(early_arrival_time_green_et.seconds()));
336 auto early_arrival_state_green_et_optional = traffic_light->predictState(lanelet::time::timeFromSec(early_arrival_time_green_et.seconds()));
338 if (!
validLightState(early_arrival_state_green_et_optional, early_arrival_time_green_et))
340 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Unable to resolve give signal...");
341 return std::make_tuple(rclcpp::Time(0), is_entry_time_within_green_or_tbd, in_tbd);
344 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"early_arrival_state_green_et: " << early_arrival_state_green_et_optional.get().second);
346 bool can_make_early_arrival = (early_arrival_state_green_et_optional.get().second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED);
349 if (can_make_early_arrival)
357 rclcpp::Time nearest_green_signal_start_time = rclcpp::Time(0);
358 if (traffic_light->fixed_cycle_duration.total_milliseconds()/1000.0 > 1.0)
360 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"UC2 Handling");
361 auto normal_arrival_state_green_et_optional = traffic_light->predictState(lanelet::time::timeFromSec(nearest_green_entry_time.seconds()));
363 if (!
validLightState(normal_arrival_state_green_et_optional, nearest_green_entry_time))
365 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Unable to resolve give signal...");
366 return std::make_tuple(rclcpp::Time(0), is_entry_time_within_green_or_tbd, in_tbd);
369 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"normal_arrival_signal_end_time: " <<
std::to_string(lanelet::time::toSec(normal_arrival_state_green_et_optional.get().first)));
372 nearest_green_signal_start_time = rclcpp::Time(lanelet::time::toSec(normal_arrival_state_green_et_optional.get().first - traffic_light->signal_durations[lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED]) * 1e9);
376 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"UC3 Handling");
378 for (
size_t i = 0;
i < traffic_light->recorded_start_time_stamps.size();
i++)
380 if (traffic_light->recorded_time_stamps[
i].second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED &&
381 lanelet::time::timeFromSec(nearest_green_entry_time.seconds()) < traffic_light->recorded_time_stamps[
i].first )
383 nearest_green_signal_start_time = rclcpp::Time(lanelet::time::toSec(traffic_light->recorded_start_time_stamps[
i]) * 1e9);
388 if (nearest_green_signal_start_time == rclcpp::Time(0))
390 nearest_green_signal_start_time = rclcpp::Time(lanelet::time::toSec(traffic_light->recorded_time_stamps.back().first) * 1e9);
413 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"Earliest entry time... has gone past the cashed entering time. nearest_green_entry_time_cached_ (which can also be TBD):" <<
std::to_string(
nearest_green_entry_time_cached_.get().seconds()) <<
", and earliest_entry_time: " <<
std::to_string(earliest_entry_time.seconds()));
415 return std::make_tuple(nearest_green_entry_time, is_entry_time_within_green_or_tbd, in_tbd);
422 return free_flow_speed;
424 else if (x1 >
x &&
x >= x2)
426 return std::sqrt((2 *
x * max_accel * max_decel + max_decel * std::pow(current_speed, 2) - max_accel * (std::pow(departure_speed, 2)))/(max_decel - max_accel));
430 if (current_speed <= departure_speed)
432 return std::sqrt(2 *
x * max_accel + std::pow(current_speed, 2));
436 return std::sqrt(2 *
x * max_decel + std::pow(current_speed, 2));
447 t_entry = 2*entry_dist/(current_speed + departure_speed);
456 distances.
dx1 = ((pow(v_max, 2) - pow(v0, 2)) / (2 * a_max)) + ((pow(v1, 2) - pow(v_max, 2)) / (2 * a_min));
458 distances.
dx2 = ((pow(v1, 2) - pow(v0, 2)) / (2 * a_max));
460 distances.
dx2 = ((pow(v1, 2) - pow(v0, 2)) / (2 * a_min));
462 distances.
dx3 = ((pow(v_min, 2) - pow(v0, 2)) / (2 * a_min)) + ((pow(v1, 2) - pow(v_min, 2)) / (2 * a_max));
463 distances.
dx4 = ((pow(v_min, 2) - pow(v0, 2)) / (2 * a_min));
464 distances.
dx5 = - pow(v0, 2) / (2 * a_min);
471 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"\n");
472 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"t0: " <<
std::to_string(params.
t0_));
473 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"v0: " << params.
v0_);
474 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"x0: " << params.
x0_);
476 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"t1: " <<
std::to_string(params.
t1_));
477 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"v1: " << params.
v1_);
478 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"x1: " << params.
x1_);
479 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"a1: " << params.
a1_);
481 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"t2: " <<
std::to_string(params.
t2_));
482 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"v2: " << params.
v2_);
483 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"x2: " << params.
x2_);
484 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"a2: " << params.
a2_);
486 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"t3: " <<
std::to_string(params.
t3_));
487 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"v3: " << params.
v3_);
488 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"x3: " << params.
x3_);
489 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"a3: " << params.
a3_);
491 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"\n");
496 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"\n");
497 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"dx1: " << delta_xs.
dx1);
498 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"dx2: " << delta_xs.
dx2);
499 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"dx3: " << delta_xs.
dx3);
500 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"dx4: " << delta_xs.
dx4);
501 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"dx5: " << delta_xs.
dx5 <<
"\n");
504std::vector<TrajectoryParams>
LCIStrategicPlugin::get_boundary_traj_params(
double t,
double v0,
double v1,
double v_max,
double v_min,
double a_max,
double a_min,
double x0,
double x_end,
double dx,
BoundaryDistances boundary_distances)
506 double dx1 = boundary_distances.
dx1;
507 double dx2 = boundary_distances.
dx2;
508 double dx3 = boundary_distances.
dx3;
509 double dx4 = boundary_distances.
dx4;
510 double dx5 = boundary_distances.
dx5;
576 return {traj1, traj2, traj3, traj4, traj5, traj6, traj7, traj8};
579TrajectoryParams LCIStrategicPlugin::get_ts_case(
double t,
double et,
double v0,
double v1,
double v_max,
double v_min,
double a_max,
double a_min,
double x0,
double x_end,
double dx,
BoundaryDistances boundary_distances, std::vector<TrajectoryParams> params)
581 double dx1 = boundary_distances.
dx1;
582 double dx2 = boundary_distances.
dx2;
583 double dx3 = boundary_distances.
dx3;
584 double dx4 = boundary_distances.
dx4;
585 double dx5 = boundary_distances.
dx5;
587 if (params.size() != 8)
589 throw std::invalid_argument(
"Not enough trajectory paras given! Given size: " +
std::to_string(params.size()));
603 if (traj1.
t3_ <= et && et < traj2.
t3_)
605 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CALCULATED: case 1");
606 veh_traj =
ts_case1(t, et, v0, v1, v_max, a_max, a_min, x0, x_end, dx);
609 else if (traj2.
t3_ <= et && et < traj3.
t3_)
611 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CALCULATED: case 2");
612 veh_traj =
ts_case2(t, et, v0, v1, a_max, a_min, x0, x_end, dx);
615 else if (traj3.
t3_ <= et && et < traj4.
t3_)
617 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CALCULATED: case 3");
618 veh_traj =
ts_case3(t, et, v0, v1, a_max, a_min, x0, x_end, dx);
621 else if (traj4.
t3_ <= et && et < traj5.
t3_)
623 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CALCULATED: case 4");
624 veh_traj =
ts_case4(t, et, v0, v1, v_min, a_max, a_min, x0, x_end, dx);
627 else if (traj5.
t3_ <= et && et < traj6.
t3_)
629 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CALCULATED: case 5");
630 veh_traj =
ts_case5(t, et, v0, a_max, a_min, x0, x_end, dx);
633 else if (traj6.
t3_ <= et && et < traj7.
t3_)
635 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CALCULATED: case 6");
636 veh_traj =
ts_case6(t, et, v0, v_min, a_min, x0, x_end, dx, dx3, traj6);
639 else if (traj7.
t3_ <= et && et <= traj8.
t3_)
641 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CALCULATED: case 7");
642 veh_traj =
ts_case7(t, et, v0, v_min, a_min, x0, x_end, dx);
647 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CALCULATED: case 8");
648 veh_traj =
ts_case8(dx, dx5, traj8);
665 double nom1 = 2 * dx * (((1 - (a_max / a_min)) * v_max) + ((a_max / a_min) * v1) - v0);
666 double nom2 = dt * (((1 - (a_max / a_min)) * pow(v_max, 2)) + ((a_max / a_min) * pow(v1, 2)) - pow(v0, 2));
667 double den = pow(v_max - v0, 2) - ((a_max / a_min) * pow(v_max - v1, 2));
669 if (den <= epsilon_ && den >= -
epsilon_)
670 throw std::invalid_argument(
"CASE1: Received den near zero..." +
std::to_string(den));
672 double tc = (nom1 - nom2) / den;
676 if (dt - tc <= epsilon_ && dt - tc >= -
epsilon_)
677 throw std::invalid_argument(
"CASE1: Received dt - tc near zero..." +
std::to_string(dt - tc));
679 traj.
a1_ = (((1 - (a_max / a_min)) * v_max) + ((a_max / a_min) * v1) - v0) / (dt - tc);
683 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CASE1: Received traj.a1_ near zero...");
684 traj.
t1_ = traj.
t0_ + ((dt - tc) * (a_max / (a_min + a_max)));
690 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
695 traj.
x2_ = traj.
x1_ + (v_max * tc);
698 traj.
a3_ = traj.
a1_ * (a_min / a_max);
715 if (dt <= epsilon_ && dt >= -
epsilon_)
716 throw std::invalid_argument(
"CASE2: Received dt near zero..." +
std::to_string(dt));
718 double sqr1 = pow(1 - (a_max / a_min), 2) * pow(dx / dt, 2);
719 double sqr2 = (1 - (a_max / a_min)) * (((a_max / a_min) * v1 * (v1 - (2 * dx / dt))) + (v0 * ((2 * dx / dt) - v0)));
720 double v_hat = (dx / dt) + (sqrt(sqr1 - sqr2) / (1 - (a_max / a_min)));
723 traj.
a1_ = (((1 - (a_max / a_min)) * v_hat) + ((a_max / a_min) * v1) - v0) / dt;
727 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CASE2: Received traj.a1_ near zero...");
728 traj.
t1_ = traj.
t0_ + (dt * (a_max / (a_min + a_max)));
734 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
738 traj.
a2_ = traj.
a1_ * a_min / a_max;
742 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CASE2: Received traj.a2_ near zero...");
743 traj.
t2_ = traj.
t1_ + (dt * (a_min / (a_min + a_max)));
769 if (dt <= epsilon_ && dt >= -
epsilon_)
770 throw std::invalid_argument(
"CASE3: Received dt near zero..." +
std::to_string(dt));
772 double sqr1 = pow((a_max / a_min) - 1, 2) * pow(dx / dt, 2);
773 double sqr2 = ((a_max / a_min) - 1) * ((v1 * (v1 - (2 * dx / dt))) + ((a_max / a_min) * v0 * ((2 * dx / dt) - v0)));
774 double v_hat = (dx / dt) + (sqrt(sqr1 - sqr2) / ((a_max / a_min) - 1));
777 traj.
a1_ = (((1 - (a_min / a_max)) * v_hat) + ((a_min / a_max) * v1) - v0) / dt;
781 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CASE3: Received traj.a1_ near zero...");
782 traj.
t1_ = traj.
t0_ + (dt * (a_max / (a_min + a_max)));
788 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
792 traj.
a2_ = traj.
a1_ * a_max / a_min;
812 double nom1 = 2 * dx * ((((a_max / a_min) - 1) * v_min) + v1 - ((a_max / a_min) * v0));
813 double nom2 = dt * ((((a_max / a_min) - 1) * pow(v_min, 2)) + pow(v1, 2) - ((a_max / a_min) * pow(v0, 2)));
814 double den = ((a_max / a_min) * pow(v_min - v0, 2)) - pow(v_min - v1, 2);
816 if (den <= epsilon_ && den >= -
epsilon_)
817 throw std::invalid_argument(
"CASE4: Received den near zero..." +
std::to_string(den));
819 double tc = (nom1 - nom2) / den;
823 if (dt - tc <= epsilon_ && dt - tc >= -
epsilon_)
824 throw std::invalid_argument(
"CASE4: Received dt - tc near zero..." +
std::to_string(dt - tc));
826 traj.
a1_ = (((1 - (a_min / a_max)) * v_min) + ((a_min / a_max) * v1) - v0) / (dt - tc);
830 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CASE4: Received traj.a1_ near zero...");
831 traj.
t1_ = traj.
t0_ + ((dt - tc) * (a_min / (a_min + a_max)));
837 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
843 traj.
x2_ = traj.
x1_ + (v_min * tc);
846 traj.
a3_ = traj.
a1_ * a_max / a_min;
862 double sqr = ((a_max / a_min) - 1) * ((2 * a_min * (dx - (v0 * dt))) - pow(a_min * dt, 2));
863 double v_hat = (v0 + (a_min * dt)) - (sqrt(sqr) / ((a_max / a_min) - 1));
864 double v_p = ((1 - (a_max / a_min)) * v_hat) + ((a_max / a_min) * v0) + (a_max * dt);
870 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
898 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
905 tc = traj6.
t2_ - traj6.
t1_;
910 traj.
x2_ = traj.
x1_ + (v_min * tc);
912 double dt_p = dt - (traj.
t1_ - traj.
t0_) - tc;
914 if (dt_p <= epsilon_ && dt_p >= -
epsilon_)
915 throw std::invalid_argument(
"CASE6: Received dt_p near zero..." +
std::to_string(dt_p));
917 double v_p = ((2 * a_min * (dx - (v_min * tc))) - (pow(v_min, 2) - pow(v0, 2)) - (v_min * dt_p * a_min)) / (dt_p * a_min);
920 traj.
a3_ = (v_p - v_min) / dt_p;
938 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
941 double v_p = v_min - sqrt(pow(v_min - v0, 2) - (2 * a_min * ((v_min * dt) - dx)));
942 double dt_p = (v_p - v_min) / a_min;
944 if (dt_p <= epsilon_ && dt_p >= -
epsilon_)
945 throw std::invalid_argument(
"CASE7: Received dt_p near zero..." +
std::to_string(dt_p));
947 double tc = dt - ((v_p - v0) / a_min);
952 traj.
x2_ = traj.
x1_ + (v_min * tc);
955 traj.
a3_ = (v_p - v_min) / dt_p;
968 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"CASE8: Not within safe stopping distance originally planned!");
979 t_end = t + (sqrt(pow(v0, 2) + (2 * a_max * dx)) - v0)/a_max;
981 t_end = t + (sqrt(pow(v0, 2) + (2 * a_min * dx)) - v0) / a_min;
994 traj.v1_ = sqrt(pow(v0, 2) + (2 * a_max * dx));
999 traj.v1_ = sqrt(pow(v0, 2) + (2 * a_min * dx));
1004 traj.t2_ = traj.t1_;
1006 traj.v2_ = traj.v1_;
1007 traj.x2_ = traj.x1_;
1009 traj.t3_ = traj.t1_;
1011 traj.v3_ = traj.v1_;
1012 traj.x3_ = traj.x1_;
1020 double v_hat = sqrt(((2 * dx * a_max * a_min) + (a_min * pow(v0, 2)) - (a_max * pow(v1, 2))) / (a_min - a_max));
1021 double t_end = t + ((v_hat * (a_min - a_max)) - (v0 * a_min) + (v1 * a_max)) / (a_max * a_min);
1033 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
1051 double t_end = t + (dx / v_max) + (pow(v_max - v0, 2) / (2 * a_max * v_max)) - (pow(v1 - v_max, 2) / (2 * a_min * v_max));
1062 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
1066 traj.
t2_ = t_end - ((v1 - v_max) / a_min);
1067 traj.
x2_ = x_end - ((pow(v1, 2) - pow(v_max, 2)) / (2 * a_min));
1079 double nom = (v_max - v0) + ((a_max / a_min) * (v1 - v_max));
1080 double den = (pow(v_max, 2) - pow(v0, 2)) + ((a_max / a_min) * (pow(v1, 2) - pow(v_max, 2)));
1082 if (den <= epsilon_ && den >= -
epsilon_)
1083 throw std::invalid_argument(
"boundary_accel_nocruise_maxspeed_decel: Received den near zero..." +
std::to_string(den));
1085 double t_end = t + (2 * dx * nom / den);
1093 double dt = t_end - t;
1098 if (dt - tc <= epsilon_ && dt - tc >= -
epsilon_)
1099 throw std::invalid_argument(
"boundary_accel_nocruise_maxspeed_decel: Received dt - tc near zero..." +
std::to_string(dt - tc));
1101 traj.a1_ = (((1 - (a_max / a_min)) * v_max) + ((a_max / a_min) * v1) - v0) / (dt - tc);
1105 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"lci_strategic_plugin"),
"boundary_accel_nocruise_maxspeed_decel: Received traj.a1_ near zero...");
1106 traj.t1_ = traj.t0_ + (dt * (a_max / (a_min + a_max)));
1107 traj.x1_ = traj.x0_ + (v_max * (traj.t1_ - traj.t0_));
1111 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1112 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1116 traj.a2_ = ((((a_min / a_max) - 1) * v_max) + v1 - ((a_min / a_max) * v0)) / (dt - tc);
1120 traj.t3_ = traj.t2_;
1122 traj.v3_ = traj.v2_;
1123 traj.x3_ = traj.x2_;
1130 if (v0 + v1 <= epsilon_ && v0 + v1 >= -
epsilon_)
1131 throw std::invalid_argument(
"boundary_accel_or_decel_complete_upper: Received v0 + v1 near zero..." +
std::to_string(v0 + v1));
1133 double t_end = t + ((2 * dx) / (v0 + v1));
1143 if (dx <= epsilon_ && dx >= -
epsilon_)
1144 throw std::invalid_argument(
"boundary_accel_or_decel_complete_upper: Received dx near zero..." +
std::to_string(dx));
1146 traj.a1_ = (pow(v1, 2) - pow(v0, 2)) / (2 * dx);
1150 traj.t2_ = traj.t1_;
1152 traj.v2_ = traj.v1_;
1153 traj.x2_ = traj.x1_;
1155 traj.t3_ = traj.t1_;
1157 traj.v3_ = traj.v1_;
1158 traj.x3_ = traj.x1_;
1165 double v_hat = sqrt(((2 * dx * a_max * a_min) + (a_max * pow(v0, 2)) - (a_min * pow(v1, 2))) / (a_max - a_min));
1166 double t_end = t + ((v_hat * (a_max - a_min)) - (v0 * a_max) + (v1 * a_min)) / (a_max * a_min);
1177 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
1194 double sqr = sqrt((2 * a_max * dx) - ((pow(v_min, 2) - pow(v0, 2)) * (a_max / a_min)) + pow(v_min, 2));
1196 double t_end = t + ((sqr - v_min) / a_max) + ((v_min - v0) / a_min);
1207 traj.
x1_ = traj.
x0_ + (pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * a_min);
1224 double nom = (v1 - v_min) + ((a_max / a_min) * (v_min - v0));
1225 double den = (pow(v1, 2) - pow(v_min, 2)) + ((a_max / a_min) * (pow(v_min, 2) - pow(v0, 2)));
1227 if (den <= epsilon_ && den >= -
epsilon_)
1228 throw std::invalid_argument(
"boundary_decel_nocruise_minspeed_accel_complete: Received den near zero..." +
std::to_string(den));
1230 double t_end = t + (2 * dx * nom / den);
1237 double dt = t_end - t;
1242 if (dt - tc <= epsilon_ && dt - tc >= -
epsilon_)
1243 throw std::invalid_argument(
"boundary_decel_nocruise_minspeed_accel_complete: Received dt - tc near zero..." +
std::to_string(dt - tc));
1245 traj.a1_ = (((1 - (a_min / a_max)) * v_min) + ((a_min / a_max) * v1) - v0) / (dt - tc);
1246 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1247 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1250 traj.a2_ = ((((a_max / a_min) - 1) * v_min) + v1 - ((a_max / a_min) * v0)) / (dt - tc);
1254 traj.t3_ = traj.t2_;
1256 traj.v3_ = traj.v2_;
1257 traj.x3_ = traj.x2_;
1263 double t_end = t + (dx / v_min) + ((pow(v_min - v0, 2)) / (2 * a_min * v_min)) - ((pow(v1 - v_min, 2)) / (2 * a_max * v_min));
1274 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
1278 traj.
t2_ = t_end - ((v1 - v_min) / a_max);
1279 traj.
x2_ = x_end - ((pow(v1, 2) - pow(v_min, 2)) / (2 * a_max));
1291 double t_end = t + (dx / v_min) + (pow(v_min - v0, 2) / (2 * a_min * v_min));
1302 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
1318 double t_end = t + (sqrt(pow(v0, 2) + (2 * a_min * dx)) - v0) / a_min;
1327 traj.v1_ = sqrt(pow(v0, 2) + (2 * a_min * dx));
1331 traj.t2_ = traj.t1_;
1333 traj.v2_ = traj.v1_;
1334 traj.x2_ = traj.x1_;
1336 traj.t3_ = traj.t1_;
1338 traj.v3_ = traj.v1_;
1339 traj.x3_ = traj.x1_;
1345 double t_end = t + (dx / v_min) + (v0 * (v0 - (2 * v_min)) / (2 * a_min * v_min));
1356 traj.
x1_ = traj.
x0_ + ((pow(traj.
v1_, 2) - pow(traj.
v0_, 2)) / (2 * traj.
a1_));
1360 traj.
t2_ = t_end - ((0 - traj.
v2_) / a_min);
1361 traj.
x2_ = x_end - ((0 - pow(traj.
v2_, 2)) / (2 * a_min));
TrajectoryParams boundary_decel_nocruise_notminspeed_accel(double t, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_cruise_minspeed_decel(double t, double v0, double v_min, double a_min, double x0, double x_end, double dx)
LCIStrategicPluginConfig config_
Config containing configurable algorithm parameters.
BoundaryDistances get_delta_x(double v0, double v1, double v_max, double v_min, double a_max, double a_min)
Get boundary distances used to compare against current state in order to create trajectory smoothing ...
double get_distance_to_accel_or_decel_twice(double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
Get required distance to accel then decel, or vise versa - each at least once - to reach departure_sp...
rclcpp::Time get_eet_or_tbd(const rclcpp::Time &earliest_entry_time, const lanelet::CarmaTrafficSignalPtr &signal) const
Returns the later of earliest_entry_time or the end of the available signal states in the traffic_sig...
double estimate_time_to_stop(double d, double v) const
Helper method to use basic kinematics to compute an estimated stopping time from from the inputs.
bool validLightState(const boost::optional< std::pair< boost::posix_time::ptime, lanelet::CarmaTrafficSignalState > > &optional_state, const rclcpp::Time &source_time) const
Helper method that checks both if the input optional light state is set and if the state it contains ...
TrajectoryParams ts_case7(double t, double et, double v0, double v_min, double a_min, double x0, double x_end, double dx)
boost::optional< rclcpp::Time > nearest_green_entry_time_cached_
TrajectoryParams boundary_accel_nocruise_maxspeed_decel(double t, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams ts_case1(double t, double et, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
Trajectory Smoothing Algorithm 8 cases. TSMO UC2, UC3 algorithm equations.
TrajectoryParams boundary_accel_or_decel_complete_upper(double t, double v0, double v1, double x0, double x_end, double dx)
std::optional< rclcpp::Time > get_nearest_green_entry_time(const rclcpp::Time ¤t_time, const rclcpp::Time &earliest_entry_time, const lanelet::CarmaTrafficSignalPtr &signal, double minimum_required_green_time=0.0) const
Provides the scheduled entry time for the vehicle in the future. This scheduled time is the earliest ...
TrajectoryParams boundary_accel_or_decel_incomplete_upper(double t, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
unsigned long long scheduled_enter_time_
double calc_estimated_entry_time_left(double entry_dist, double current_speed, double departure_speed) const
calculate the time vehicle will enter to intersection with optimal deceleration
rclcpp::Duration get_earliest_entry_time(double remaining_distance, double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
Gets the earliest entry time into the intersection that is kinematically possible for the vehicle....
TrajectoryParams boundary_accel_nocruise_notmaxspeed_decel(double t, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_nocruise_minspeed_accel_incomplete(double t, double v0, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
std::tuple< rclcpp::Time, bool, bool > get_final_entry_time_and_conditions(const VehicleState ¤t_state, const rclcpp::Time &earliest_entry_time, lanelet::CarmaTrafficSignalPtr traffic_light)
Get the final entry time from either vehicle's own internal ET calculation (TSMO UC2) or from carma-s...
TrajectoryParams boundary_accel_cruise_maxspeed_decel(double t, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_incomplete_lower(double t, double v0, double a_min, double x0, double x_end, double dx)
TrajectoryParams ts_case6(double t, double et, double v0, double v_min, double a_min, double x0, double x_end, double dx, double dx3, TrajectoryParams traj6)
TrajectoryParams ts_case4(double t, double et, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_cruise_minspeed_accel(double t, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
void print_params(TrajectoryParams params)
Helper method to print TrajectoryParams.
TrajectoryParams ts_case2(double t, double et, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams get_ts_case(double t, double et, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx, BoundaryDistances boundary_distances, std::vector< TrajectoryParams > params)
TrajectoryParams boundary_decel_nocruise_minspeed_accel_complete(double t, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
double get_distance_to_accel_or_decel_once(double current_speed, double departure_speed, double max_accel, double max_decel) const
Get required distance to accel or decel to reach departure_speed with given speed and acceleration pa...
TrajectoryParams boundary_decel_cruise_minspeed(double t, double v0, double v_min, double a_min, double x0, double x_end, double dx)
double get_inflection_speed_value(double x, double x1, double x2, double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
Get the speed between the acceleration and deceleration pieces.
double get_trajectory_smoothing_activation_distance(double time_remaining_at_free_flow, double full_cycle_duration, double current_speed, double speed_limit, double departure_speed, double max_accel, double max_decel) const
Gets maximum distance (nearest downtrack) the trajectory smoothing algorithm makes difference than si...
TrajectoryParams ts_case8(double dx, double dx5, TrajectoryParams traj8)
TrajectoryParams ts_case3(double t, double et, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
double estimate_distance_to_stop(double v, double a) const
Helper method to use basic kinematics to compute an estimated stopping distance from from the inputs.
TrajectoryParams ts_case5(double t, double et, double v0, double a_max, double a_min, double x0, double x_end, double dx)
std::vector< TrajectoryParams > get_boundary_traj_params(double t, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx, BoundaryDistances boundary_distances)
Get all possible trajectory smoothing parameters for each segments. Later this will be used to genera...
void print_boundary_distances(BoundaryDistances delta_xs)
Helper method to print TrajectoryParams.
auto to_string(const UtmZone &zone) -> std::string
bool enable_carma_streets_connection
Bool: Enable carma streets connection.
double algo_minimum_speed
Minimum allowable speed TS algorithm in m/s.
double green_light_time_buffer
A buffer in seconds around the green phase which will reduce the phase length such that vehicle still...
Struct representing a vehicle state for the purposes of planning.
bool is_algorithm_successful