scenario_simulator_v2 C++ API
transition_assertion.hpp
Go to the documentation of this file.
1 // Copyright 2015 TIER IV, Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef CONCEALER__TRANSITION_ASSERTION_HPP_
16 #define CONCEALER__TRANSITION_ASSERTION_HPP_
17 
18 #include <autoware_auto_system_msgs/msg/autoware_state.hpp>
19 #include <chrono>
20 #include <rclcpp/node.hpp>
21 #include <rclcpp/rate.hpp>
23 
24 namespace concealer
25 {
26 template <typename T>
27 auto getParameter(const std::string & name, T value = {})
28 {
29  rclcpp::Node node{"get_parameter", "simulation"};
30 
31  node.declare_parameter<T>(name, value);
32  node.get_parameter<T>(name, value);
33 
34  return value;
35 }
36 
37 template <typename Autoware>
39 {
40  using clock_type = std::chrono::steady_clock;
41  using rate_type = rclcpp::GenericRate<clock_type>;
42 
43  const clock_type::time_point start;
44  const std::chrono::seconds initialize_duration;
45 
47  : start(clock_type::now()),
48  initialize_duration(std::chrono::seconds(getParameter<int>("initialize_duration")))
49  {
50  }
51 
52  auto makeTransitionError(const std::string & expected) const
53  {
54  const auto current_state = asAutoware().getAutowareStateName();
55  using namespace std::chrono;
56  return common::AutowareError(
57  "Simulator waited for the Autoware state to transition to ", expected,
58  ", but time is up. The current Autoware state is ",
59  (current_state.empty() ? "NOT PUBLISHED YET" : current_state), ".");
60  }
61 
62  auto asAutoware() -> Autoware & { return static_cast<Autoware &>(*this); }
63  auto asAutoware() const -> const Autoware & { return static_cast<const Autoware &>(*this); }
64 
65 #define DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE_WITH_INITIALIZE_TIME_LIMIT(STATE) \
66  template <typename Thunk = void (*)()> \
67  void waitForAutowareStateToBe##STATE( \
68  Thunk && thunk = [] {}, std::chrono::seconds interval = std::chrono::seconds(1)) \
69  { \
70  using std::chrono::duration_cast; \
71  using std::chrono::seconds; \
72  rate_type rate(interval); \
73  for (thunk(); not asAutoware().isStopRequested() and not asAutoware().is##STATE(); \
74  rate.sleep()) { \
75  auto now = clock_type::now(); \
76  if (start + initialize_duration <= now) { \
77  throw makeTransitionError(#STATE); \
78  } else { \
79  RCLCPP_INFO_STREAM( \
80  asAutoware().get_logger(), \
81  "Simulator waiting for Autoware state to be " #STATE " (remain: " \
82  << duration_cast<seconds>(start + initialize_duration - now).count() << ")."); \
83  thunk(); \
84  } \
85  } \
86  RCLCPP_INFO_STREAM( \
87  asAutoware().get_logger(), \
88  "Autoware is " << asAutoware().getAutowareStateName() << " now."); \
89  } \
90  static_assert(true, "")
91 
92 #define DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE(STATE) \
93  template <typename Thunk = void (*)()> \
94  void waitForAutowareStateToBe##STATE( \
95  Thunk && thunk = [] {}, std::chrono::seconds interval = std::chrono::seconds(1)) \
96  { \
97  using std::chrono::duration_cast; \
98  using std::chrono::seconds; \
99  rate_type rate(interval); \
100  for (thunk(); not asAutoware().isStopRequested() and not asAutoware().is##STATE(); \
101  rate.sleep()) { \
102  auto now = clock_type::now(); \
103  RCLCPP_INFO_STREAM( \
104  asAutoware().get_logger(), \
105  "Simulator waiting for Autoware state to be " #STATE " (remain: " \
106  << duration_cast<seconds>(start + initialize_duration - now).count() << ")."); \
107  thunk(); \
108  } \
109  RCLCPP_INFO_STREAM( \
110  asAutoware().get_logger(), \
111  "Autoware is " << asAutoware().getAutowareStateName() << " now."); \
112  } \
113  static_assert(true, "")
114 
115  // XXX: The time limit must be ignored in waitForAutowareStateToBeDriving() because the current
116  // implementation attempts to transition to Driving state after initialize_duration seconds have
117  // elapsed.
118 
126 
127 #undef DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE
128 };
129 } // namespace concealer
130 
131 #endif // CONCEALER__TRANSITION_ASSERTION_HPP_
Definition: autoware.hpp:38
Definition: autoware.hpp:30
auto getParameter(const std::string &name, T value={})
Definition: transition_assertion.hpp:27
Definition: cache.hpp:27
std::string string
Definition: junit5.hpp:26
Autoware encountered some problem that led to a simulation failure.
Definition: exception.hpp:41
Definition: transition_assertion.hpp:39
auto asAutoware() const -> const Autoware &
Definition: transition_assertion.hpp:63
DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE(Finalizing)
rclcpp::GenericRate< clock_type > rate_type
Definition: transition_assertion.hpp:41
const clock_type::time_point start
Definition: transition_assertion.hpp:43
DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE(ArrivedGoal)
DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE_WITH_INITIALIZE_TIME_LIMIT(WaitingForRoute)
DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE_WITH_INITIALIZE_TIME_LIMIT(WaitingForEngage)
TransitionAssertion()
Definition: transition_assertion.hpp:46
std::chrono::steady_clock clock_type
Definition: transition_assertion.hpp:40
auto asAutoware() -> Autoware &
Definition: transition_assertion.hpp:62
DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE_WITH_INITIALIZE_TIME_LIMIT(Planning)
const std::chrono::seconds initialize_duration
Definition: transition_assertion.hpp:44
auto makeTransitionError(const std::string &expected) const
Definition: transition_assertion.hpp:52
DEFINE_WAIT_FOR_AUTOWARE_STATE_TO_BE_WITH_INITIALIZE_TIME_LIMIT(Initializing)