scenario_simulator_v2 C++ API
custom_command_action.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 OPENSCENARIO_INTERPRETER__SYNTAX__CUSTOM_COMMAND_ACTION_HPP_
16 #define OPENSCENARIO_INTERPRETER__SYNTAX__CUSTOM_COMMAND_ACTION_HPP_
17 
20 #include <pugixml.hpp>
21 #include <rclcpp/rclcpp.hpp>
22 #include <string>
23 #include <tier4_simulation_msgs/msg/simulation_events.hpp>
24 #include <vector>
25 
27 {
28 inline namespace syntax
29 {
30 template <int Value>
31 struct SpecialAction : public std::integral_constant<int, Value>
32 {
33 };
34 
35 template <>
36 class SpecialAction<EXIT_FAILURE> : public std::integral_constant<int, EXIT_FAILURE>,
37  public std::runtime_error
38 {
39  const std::function<std::string(const std::string &)> make_message;
40  const std::string source_name;
41  const std::string path;
42 
43  template <typename... Ts>
44  static auto concatenate(Ts &&... xs)
45  {
46  std::stringstream ss;
47  (ss << ... << xs);
48  return ss.str();
49  }
50 
51  template <typename Container>
52  struct comma_separated
53  {
54  const Container & container;
55  const std::function<void(std::ostream &, const typename Container::value_type &)> print;
56 
57  template <typename Printer>
58  explicit comma_separated(const Container & container, Printer && print)
59  : container{container}, print{std::forward<decltype(print)>(print)}
60  {
61  }
62 
63  friend auto operator<<(std::ostream & os, const comma_separated & cs) -> std::ostream &
64  {
65  auto separator = "";
66  for (const auto & value : cs.container) {
67  os << std::exchange(separator, ", ");
68  cs.print(os, value);
69  }
70  return os;
71  }
72  };
73 
74  template <typename Conditions>
75  static auto makeMessage(
76  const std::string & trigger_name, const std::string & trigger_path,
77  const Conditions & conditions)
78  {
79  std::stringstream what;
80  what << "CustomCommandAction typed " << std::quoted("exitFailure") << " was triggered by the ";
81  const auto anonymous = std::any_of(
82  conditions.begin(), conditions.end(),
83  [](const auto & condition) { return condition.first.empty(); });
84  switch (conditions.size()) {
85  case 0:
86  what << trigger_name << " (" << trigger_path << ")";
87  break;
88  case 1:
89  if (anonymous) {
90  what << "anonymous " << trigger_name << " (" << trigger_path << "." << trigger_name
91  << "[0]): " << conditions[0].second;
92  } else {
93  what << trigger_name << " named " << std::quoted(conditions[0].first) << ": "
94  << conditions[0].second;
95  }
96  break;
97  default:
98  if (anonymous) {
99  what << "anonymous " << trigger_name << "s (" << trigger_path << "." << trigger_name
100  << "[...]): "
101  << comma_separated(conditions, [i = 0](auto & os, const auto & condition) mutable {
102  os << '{' << std::quoted(std::to_string(i++)) << ": " << condition.second
103  << '}';
104  });
105  } else {
106  what << "named " << trigger_name << "s {"
107  << comma_separated(
108  conditions,
109  [](auto & os, const auto & condition) { os << std::quoted(condition.first); })
110  << "}: " << comma_separated(conditions, [](auto & os, const auto & condition) {
111  os << '{' << std::quoted(condition.first) << ": " << condition.second << '}';
112  });
113  }
114  break;
115  }
116  return what.str();
117  }
118 
119 public:
121  : std::runtime_error{
122  "CustomCommandAction typed \"exitFailure\" was triggered on an unexpected code path. This is "
123  "a simulator bug. Report this to the simulator developer."}
124  {
125  }
126 
127  explicit SpecialAction(
128  const std::function<std::string(const std::string &)> & make_message,
129  const std::string & source_name, const std::string & path)
130  : std::runtime_error{make_message(path)},
131  make_message{make_message},
132  source_name{source_name},
133  path{path}
134  {
135  }
136 
137  // Constructor with no inner object - first object with conditions
138  explicit SpecialAction(
139  const std::string & source_name, const std::string & element_name, int element_index,
140  const std::string & trigger_name,
141  const std::vector<std::pair<std::string, std::string>> & conditions = {})
142  : SpecialAction{
143  [trigger_name, conditions](const auto & trigger_path) {
144  return makeMessage(trigger_name, trigger_path, conditions);
145  },
146  source_name, concatenate('.', element_name, '[', element_index, ']')}
147  {
148  }
149 
150  // Constructor with inner object and current source (to be forwarded) - intermediate object
151  explicit SpecialAction(
152  const std::string & source_name, const std::string & element_name, int element_index,
153  SpecialAction const & inner)
154  : SpecialAction{
155  inner.make_message, source_name,
156  concatenate(
157  '.', element_name, '[',
158  (inner.source_name.empty() ? std::to_string(element_index) : '"' + inner.source_name + '"'),
159  ']', inner.path)}
160  {
161  }
162 
163  // Constructor with inner but without current source -- last object
164  explicit SpecialAction(const std::string & element_name, const SpecialAction & inner)
165  : SpecialAction{
166  inner.make_message, "",
167  concatenate(
168  element_name, (inner.source_name.empty() ? "" : "." + inner.source_name), inner.path)}
169  {
170  }
171 };
172 
174 {
175  const std::vector<std::string> parameters;
176 
177  CustomCommand() = default;
178 
179  CustomCommand(const CustomCommand &) = default;
180 
182 
183  explicit CustomCommand(const std::vector<std::string> & parameters) : parameters(parameters) {}
184 
185  virtual ~CustomCommand() = default;
186 
187  virtual auto accomplished() noexcept -> bool { return true; }
188 
189  virtual auto endsImmediately() const -> bool { return true; }
190 
191  virtual auto run() noexcept -> void {}
192 
193  virtual auto start(const Scope &) -> void {}
194 };
195 
196 /* ---- CustomCommandAction ----------------------------------------------------
197  *
198  * <xsd:complexType name="CustomCommandAction">
199  * <xsd:simpleContent>
200  * <xsd:extension base="xsd:string">
201  * <xsd:attribute name="type" type="String" use="required"/>
202  * </xsd:extension>
203  * </xsd:simpleContent>
204  * </xsd:complexType>
205  *
206  * -------------------------------------------------------------------------- */
207 struct CustomCommandAction : private Scope
208 {
209  const String type;
210 
212 
213 private:
214  const std::shared_ptr<CustomCommand> command;
215 
216 public:
217  explicit CustomCommandAction(const pugi::xml_node &, const Scope &);
218 
219  auto accomplished() noexcept -> bool { return command->accomplished(); }
220 
221  auto endsImmediately() const -> bool { return command->endsImmediately(); }
222 
223  auto run() noexcept -> void { return command->run(); }
224 
225  auto start() -> void { command->start(local()); }
226 };
227 } // namespace syntax
228 } // namespace openscenario_interpreter
229 
230 #endif // OPENSCENARIO_INTERPRETER__SYNTAX__CUSTOM_COMMAND_ACTION_HPP_
Definition: scope.hpp:154
auto local() const noexcept -> const Scope &
Definition: scope.cpp:125
SpecialAction()
Definition: custom_command_action.hpp:120
SpecialAction(const std::string &element_name, const SpecialAction &inner)
Definition: custom_command_action.hpp:164
SpecialAction(const std::string &source_name, const std::string &element_name, int element_index, const std::string &trigger_name, const std::vector< std::pair< std::string, std::string >> &conditions={})
Definition: custom_command_action.hpp:138
SpecialAction(const std::string &source_name, const std::string &element_name, int element_index, SpecialAction const &inner)
Definition: custom_command_action.hpp:151
SpecialAction(const std::function< std::string(const std::string &)> &make_message, const std::string &source_name, const std::string &path)
Definition: custom_command_action.hpp:127
auto concatenate
Definition: concatenate.hpp:27
auto operator<<(std::ostream &, const Boolean &) -> std::ostream &
Definition: boolean.cpp:46
std::string String
Definition: string.hpp:24
Definition: hypot.hpp:22
Definition: cache.hpp:27
char const * to_string(const RoutingGraphType &)
Definition: routing_graph_type.cpp:21
Definition: junit5.hpp:25
std::string string
Definition: junit5.hpp:26
Definition: custom_command_action.hpp:208
auto endsImmediately() const -> bool
Definition: custom_command_action.hpp:221
auto run() noexcept -> void
Definition: custom_command_action.hpp:223
const String content
Definition: custom_command_action.hpp:211
CustomCommandAction(const pugi::xml_node &, const Scope &)
Definition: custom_command_action.cpp:340
auto start() -> void
Definition: custom_command_action.hpp:225
const String type
Definition: custom_command_action.hpp:209
auto accomplished() noexcept -> bool
Definition: custom_command_action.hpp:219
Definition: custom_command_action.hpp:174
virtual auto start(const Scope &) -> void
Definition: custom_command_action.hpp:193
const std::vector< std::string > parameters
Definition: custom_command_action.hpp:175
virtual auto run() noexcept -> void
Definition: custom_command_action.hpp:191
virtual auto accomplished() noexcept -> bool
Definition: custom_command_action.hpp:187
CustomCommand(const std::vector< std::string > &parameters)
Definition: custom_command_action.hpp:183
virtual auto endsImmediately() const -> bool
Definition: custom_command_action.hpp:189
CustomCommand(const CustomCommand &)=default
Definition: custom_command_action.hpp:32