Auterion App SDK
Auterion SDK is a library that can be used by AuterionOS apps to communicate with the system.
Loading...
Searching...
No Matches
auterion.hpp
1/****************************************************************************
2 *
3 * Copyright 2023 Auterion AG. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 ****************************************************************************/
32
33#pragma once
34
35#include <atomic>
36#include <auterion_sdk/exception/exception.hpp>
37#include <functional>
38#include <rclcpp/rclcpp.hpp>
39#include <string>
40#include <thread>
41#include <variant>
42#include <vector>
43
44namespace auterion {
49class ParameterManager;
50
56struct RunOptions {
65 skip_flight_controller_connection_check = skip;
66 return *this;
67 }
68
83 skip_message_compatibility_check = skip;
84 return *this;
85 }
86
98 RunOptions& withFlightControllerConnectionTimeout(std::chrono::seconds timeout) {
99 if (timeout.count() <= 0) {
101 "flight_controller_connection_timeout must be positive (got: " +
102 std::to_string(timeout.count()) + "s)."};
103 }
104 flight_controller_connection_timeout = timeout;
105 return *this;
106 }
107
108 void validate() const {
109 if (skip_flight_controller_connection_check && !skip_message_compatibility_check) {
111 "Cannot check message compatibility if connection check is skipped. "
112 "Enable flight controller connection check, or disable message compatibility "
113 "check.");
114 }
115 }
116
117 bool skip_flight_controller_connection_check{false};
118 bool skip_message_compatibility_check{true};
119 std::chrono::seconds flight_controller_connection_timeout{15};
120};
121
122;
123
133class SDK {
134 public:
135 SDK(int argc, char** argv, const std::string& node_name);
136
137 ~SDK();
138
139 [[deprecated("Use run(RunOptions) instead, this method will be removed in a future release.")]]
145 void
147 _skip_flight_controller_connection_check = skip;
148 }
149
150 void run(RunOptions options = RunOptions());
151
152 rclcpp::Node::SharedPtr defaultRosHandle() const { return _default_ros_node; }
153
160 bool canWaitForData() const {
161 const std::thread::id executor_thread = _executor_thread.load();
162 return executor_thread != std::thread::id() &&
163 executor_thread != std::this_thread::get_id();
164 }
165
166 rclcpp::Time now() const { return _default_ros_node->now(); }
167
168 void addNode(rclcpp::Node::SharedPtr node) { _executor->add_node(node); }
169 void removeNode(rclcpp::Node::SharedPtr node) { _executor->remove_node(node); }
170
171 using ShutdownCallbackHandle = rclcpp::PreShutdownCallbackHandle;
172
182 ShutdownCallbackHandle addShutdownCallback(std::function<void()> callback);
183 void removeShutdownCallback(const ShutdownCallbackHandle& handle);
184
189 void requestShutdown(const std::string& reason);
190
191 const rclcpp::executors::SingleThreadedExecutor::UniquePtr& executor() const {
192 return _executor;
193 }
194
195 // Function to verify supported parameter types at compile time
196 template <typename T>
197 static constexpr void verify_param() {
198 static_assert(std::is_same<T, bool>::value || std::is_same<T, int64_t>::value ||
199 std::is_same<T, int>::value || std::is_same<T, float>::value ||
200 std::is_same<T, double>::value || std::is_same<T, std::string>::value ||
201 std::is_same<T, std::vector<bool>>::value ||
202 std::is_same<T, std::vector<int64_t>>::value ||
203 std::is_same<T, std::vector<int>>::value ||
204 std::is_same<T, std::vector<float>>::value ||
205 std::is_same<T, std::vector<double>>::value ||
206 std::is_same<T, std::vector<std::string>>::value,
207 "Unsupported parameter data type");
208 }
209
221 template <typename T>
222 T getParameter(const std::string& name,
223 std::function<void(const T&)> on_change_callback = nullptr) {
224 verify_param<T>();
225 }
226
237 template <typename T>
238 void setParameter(const std::string& name, const T& value) {
239 verify_param<T>();
240 setParameterValue(name, value, ParameterScope::App);
241 }
242
251 template <typename T>
252 void setSystemParameter(const std::string& full_name, const T& value) {
253 verify_param<T>();
254 setParameterValue(full_name, value, ParameterScope::System);
255 }
256
257 private:
258 using ParameterValue =
259 std::variant<bool, int64_t, int, float, double, std::string, std::vector<bool>,
260 std::vector<int64_t>, std::vector<int>, std::vector<float>,
261 std::vector<double>, std::vector<std::string>>;
262 enum class ParameterScope { App, System };
263 void setParameterValue(const std::string& name, const ParameterValue& value,
264 ParameterScope scope);
265
266 rclcpp::Node::SharedPtr _default_ros_node;
267 std::atomic<std::thread::id> _executor_thread{};
268 rclcpp::executors::SingleThreadedExecutor::UniquePtr _executor;
269 bool _skip_flight_controller_connection_check{false}; // deprecating, use RunOptions
270 std::unique_ptr<ParameterManager> _parameter_manager;
271};
272
273template <>
274bool SDK::getParameter(const std::string& name,
275 std::function<void(const bool&)> on_change_callback);
276
277template <>
278int64_t SDK::getParameter(const std::string& name,
279 std::function<void(const int64_t&)> on_change_callback);
280
281template <>
282int SDK::getParameter(const std::string& name, std::function<void(const int&)> on_change_callback);
283
284template <>
285float SDK::getParameter(const std::string& name,
286 std::function<void(const float&)> on_change_callback);
287
288template <>
289double SDK::getParameter(const std::string& name,
290 std::function<void(const double&)> on_change_callback);
291
292template <>
293std::string SDK::getParameter(const std::string& name,
294 std::function<void(const std::string&)> on_change_callback);
295
296template <>
297std::vector<bool> SDK::getParameter(
298 const std::string& name, std::function<void(const std::vector<bool>&)> on_change_callback);
299
300template <>
301std::vector<int64_t> SDK::getParameter(
302 const std::string& name, std::function<void(const std::vector<int64_t>&)> on_change_callback);
303
304template <>
305std::vector<int> SDK::getParameter(const std::string& name,
306 std::function<void(const std::vector<int>&)> on_change_callback);
307
308template <>
309std::vector<float> SDK::getParameter(
310 const std::string& name, std::function<void(const std::vector<float>&)> on_change_callback);
311
312template <>
313std::vector<double> SDK::getParameter(
314 const std::string& name, std::function<void(const std::vector<double>&)> on_change_callback);
315
316template <>
317std::vector<std::string> SDK::getParameter(
318 const std::string& name,
319 std::function<void(const std::vector<std::string>&)> on_change_callback);
320
322} // namespace auterion
Exception thrown for invalid arguments.
Definition exception.hpp:82
SDK execution class. All callbacks are called on the same thread.
Definition auterion.hpp:133
T getParameter(const std::string &name, std::function< void(const T &)> on_change_callback=nullptr)
Get a parameter value and optionally register a callback for changes.
Definition auterion.hpp:222
void requestShutdown(const std::string &reason)
Shut the app down: the shutdown callbacks run, and run() returns.
ShutdownCallbackHandle addShutdownCallback(std::function< void()> callback)
Register a callback for the app's shutdown (a signal, or requestShutdown())
void setParameter(const std::string &name, const T &value)
Set a parameter.
Definition auterion.hpp:238
bool canWaitForData() const
Whether the calling thread can wait for data the SDK receives.
Definition auterion.hpp:160
void setSkipFlightControllerConnectionCheck(bool skip)
Definition auterion.hpp:146
void setSystemParameter(const std::string &full_name, const T &value)
Set a parameter of another app or service.
Definition auterion.hpp:252
Options for SDK run() method.
Definition auterion.hpp:56
RunOptions & withSkipFlightControllerConnectionCheck(bool skip)
Skip the check for flight controller connection.
Definition auterion.hpp:64
RunOptions & withFlightControllerConnectionTimeout(std::chrono::seconds timeout)
Set the timeout for the flight controller connection check.
Definition auterion.hpp:98
RunOptions & withSkipMessageCompatibilityCheck(bool skip)
Skip the check for message compatibility.
Definition auterion.hpp:82