ros2_control - rolling
Loading...
Searching...
No Matches
gps_sensor.hpp
1// Copyright 2025 ros2_control development team
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 SEMANTIC_COMPONENTS__GPS_SENSOR_HPP_
16#define SEMANTIC_COMPONENTS__GPS_SENSOR_HPP_
17
18#include <array>
19#include <cstdint>
20#include <limits>
21#include <string>
22#include <type_traits>
23
24#include "rclcpp/version.h"
25#include "semantic_components/semantic_component_interface.hpp"
26#include "sensor_msgs/msg/nav_sat_fix.hpp"
27
28namespace semantic_components
29{
30
31enum class GPSSensorOption
32{
33 WithCovariance,
34 WithoutCovariance
35};
36
37template <GPSSensorOption sensor_option>
38class GPSSensor : public SemanticComponentInterface<sensor_msgs::msg::NavSatFix>
39{
40public:
41#if RCLCPP_VERSION_MAJOR >= 28
42 static constexpr int8_t STATUS_UNKNOWN = sensor_msgs::msg::NavSatStatus::STATUS_UNKNOWN;
43 static constexpr uint16_t SERVICE_UNKNOWN = sensor_msgs::msg::NavSatStatus::SERVICE_UNKNOWN;
44#else
45 static constexpr int8_t STATUS_UNKNOWN = -2;
46 static constexpr uint16_t SERVICE_UNKNOWN = 0;
47#endif
48
49 static_assert(
50 sensor_option == GPSSensorOption::WithCovariance ||
51 sensor_option == GPSSensorOption::WithoutCovariance,
52 "Invalid GPSSensorOption");
53 explicit GPSSensor(const std::string & name)
55 name, {{name + "/" + "status"},
56 {name + "/" + "service"},
57 {name + "/" + "latitude"},
58 {name + "/" + "longitude"},
59 {name + "/" + "altitude"}})
60 {
61 if constexpr (sensor_option == GPSSensorOption::WithCovariance)
62 {
63 interface_names_.emplace_back(name + "/" + "latitude_covariance");
64 interface_names_.emplace_back(name + "/" + "longitude_covariance");
65 interface_names_.emplace_back(name + "/" + "altitude_covariance");
66 state_interfaces_.reserve(state_interfaces_.capacity() + 3);
67 }
68 }
69
75 int8_t get_status() const
76 {
77 const auto data = state_interfaces_[0].get().get_optional();
78 if (data.has_value())
79 {
80 return static_cast<int8_t>(data.value());
81 }
82 return STATUS_UNKNOWN;
83 }
84
90 uint16_t get_service() const
91 {
92 const auto data = state_interfaces_[1].get().get_optional();
93 if (data.has_value())
94 {
95 return static_cast<uint16_t>(data.value());
96 }
97 return SERVICE_UNKNOWN;
98 }
99
105 double get_latitude() const
106 {
107 const auto data = state_interfaces_[2].get().get_optional();
108 if (data.has_value())
109 {
110 return data.value();
111 }
112 return std::numeric_limits<double>::quiet_NaN();
113 }
114
120 double get_longitude() const
121 {
122 const auto data = state_interfaces_[3].get().get_optional();
123 if (data.has_value())
124 {
125 return data.value();
126 }
127 return std::numeric_limits<double>::quiet_NaN();
128 }
129
135 double get_altitude() const
136 {
137 const auto data = state_interfaces_[4].get().get_optional();
138 if (data.has_value())
139 {
140 return data.value();
141 }
142 return std::numeric_limits<double>::quiet_NaN();
143 }
144
150 template <
151 typename U = void,
152 typename = std::enable_if_t<sensor_option == GPSSensorOption::WithCovariance, U>>
153 const std::array<double, 9> & get_covariance()
154 {
155 const auto data_1 = state_interfaces_[5].get().get_optional();
156 const auto data_2 = state_interfaces_[6].get().get_optional();
157 const auto data_3 = state_interfaces_[7].get().get_optional();
158 if (data_1.has_value())
159 {
160 covariance_[0] = data_1.value();
161 }
162 if (data_2.has_value())
163 {
164 covariance_[4] = data_2.value();
165 }
166 if (data_3.has_value())
167 {
168 covariance_[8] = data_3.value();
169 }
170 return covariance_;
171 }
172
179 bool get_values_as_message(sensor_msgs::msg::NavSatFix & message)
180 {
181 message.status.status = get_status();
182 message.status.service = get_service();
183 message.latitude = get_latitude();
184 message.longitude = get_longitude();
185 message.altitude = get_altitude();
186
187 if constexpr (sensor_option == GPSSensorOption::WithCovariance)
188 {
189 message.position_covariance = get_covariance();
190 }
191
192 return true;
193 }
194
195private:
196 std::array<double, 9> covariance_{{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
197};
198
199} // namespace semantic_components
200
201#endif // SEMANTIC_COMPONENTS__GPS_SENSOR_HPP_
Definition gps_sensor.hpp:39
double get_latitude() const
Return latitude reported by a GPS.
Definition gps_sensor.hpp:105
double get_longitude() const
Return longitude reported by a GPS.
Definition gps_sensor.hpp:120
int8_t get_status() const
Return GPS's status e.g. fix/no_fix.
Definition gps_sensor.hpp:75
bool get_values_as_message(sensor_msgs::msg::NavSatFix &message)
Fills a NavSatFix message from the current values.
Definition gps_sensor.hpp:179
const std::array< double, 9 > & get_covariance()
Return covariance reported by a GPS.
Definition gps_sensor.hpp:153
double get_altitude() const
Return altitude reported by a GPS.
Definition gps_sensor.hpp:135
uint16_t get_service() const
Return service used by GPS e.g. fix/no_fix.
Definition gps_sensor.hpp:90
Definition semantic_component_interface.hpp:29