Skip to content

Commit a89b26e

Browse files
authored
Merge branch 'master' into integrate/pal_statistics
2 parents 877ce1e + fbfc01d commit a89b26e

File tree

7 files changed

+422
-51
lines changed

7 files changed

+422
-51
lines changed

controller_interface/CMakeLists.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ if(BUILD_TESTING)
4545
)
4646

4747
ament_add_gmock(test_controller_with_options test/test_controller_with_options.cpp)
48-
install(FILES test/test_controller_node_options.yaml
49-
DESTINATION test)
5048
target_link_libraries(test_controller_with_options
5149
controller_interface
5250
)
51+
target_compile_definitions(
52+
test_controller_with_options
53+
PRIVATE PARAMETERS_FILE_PATH="${CMAKE_CURRENT_LIST_DIR}/test/")
5354

5455
ament_add_gmock(test_chainable_controller_interface test/test_chainable_controller_interface.cpp)
5556
target_link_libraries(test_chainable_controller_interface
@@ -86,6 +87,12 @@ if(BUILD_TESTING)
8687
ament_target_dependencies(test_pose_sensor
8788
geometry_msgs
8889
)
90+
91+
ament_add_gmock(test_gps_sensor test/test_gps_sensor.cpp)
92+
target_link_libraries(test_gps_sensor
93+
controller_interface
94+
hardware_interface::hardware_interface
95+
)
8996
endif()
9097

9198
install(
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
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 <string>
20+
21+
#include "semantic_components/semantic_component_interface.hpp"
22+
#include "sensor_msgs/msg/nav_sat_fix.hpp"
23+
24+
namespace semantic_components
25+
{
26+
27+
enum class GPSSensorOption
28+
{
29+
WithCovariance,
30+
WithoutCovariance
31+
};
32+
33+
template <GPSSensorOption sensor_option>
34+
class GPSSensor : public SemanticComponentInterface<sensor_msgs::msg::NavSatFix>
35+
{
36+
public:
37+
static_assert(
38+
sensor_option == GPSSensorOption::WithCovariance ||
39+
sensor_option == GPSSensorOption::WithoutCovariance,
40+
"Invalid GPSSensorOption");
41+
explicit GPSSensor(const std::string & name)
42+
: SemanticComponentInterface(
43+
name, {{name + "/" + "status"},
44+
{name + "/" + "service"},
45+
{name + "/" + "latitude"},
46+
{name + "/" + "longitude"},
47+
{name + "/" + "altitude"}})
48+
{
49+
if constexpr (sensor_option == GPSSensorOption::WithCovariance)
50+
{
51+
interface_names_.emplace_back(name + "/" + "latitude_covariance");
52+
interface_names_.emplace_back(name + "/" + "longitude_covariance");
53+
interface_names_.emplace_back(name + "/" + "altitude_covariance");
54+
}
55+
}
56+
57+
/**
58+
* Return GPS's status e.g. fix/no_fix
59+
*
60+
* \return Status
61+
*/
62+
int8_t get_status() const { return static_cast<int8_t>(state_interfaces_[0].get().get_value()); }
63+
64+
/**
65+
* Return service used by GPS e.g. fix/no_fix
66+
*
67+
* \return Service
68+
*/
69+
uint16_t get_service() const
70+
{
71+
return static_cast<uint16_t>(state_interfaces_[1].get().get_value());
72+
}
73+
74+
/**
75+
* Return latitude reported by a GPS
76+
*
77+
* \return Latitude.
78+
*/
79+
double get_latitude() const { return state_interfaces_[2].get().get_value(); }
80+
81+
/**
82+
* Return longitude reported by a GPS
83+
*
84+
* \return Longitude.
85+
*/
86+
double get_longitude() const { return state_interfaces_[3].get().get_value(); }
87+
88+
/**
89+
* Return altitude reported by a GPS
90+
*
91+
* \return Altitude.
92+
*/
93+
double get_altitude() const { return state_interfaces_[4].get().get_value(); }
94+
95+
/**
96+
* Return covariance reported by a GPS.
97+
*
98+
* \return Covariance array.
99+
*/
100+
template <
101+
typename U = void,
102+
typename = std::enable_if_t<sensor_option == GPSSensorOption::WithCovariance, U>>
103+
const std::array<double, 9> & get_covariance()
104+
{
105+
covariance_[0] = state_interfaces_[5].get().get_value();
106+
covariance_[4] = state_interfaces_[6].get().get_value();
107+
covariance_[8] = state_interfaces_[7].get().get_value();
108+
return covariance_;
109+
}
110+
111+
/**
112+
* Fills a NavSatFix message from the current values.
113+
*/
114+
bool get_values_as_message(sensor_msgs::msg::NavSatFix & message)
115+
{
116+
message.status.status = get_status();
117+
message.status.service = get_service();
118+
message.latitude = get_latitude();
119+
message.longitude = get_longitude();
120+
message.altitude = get_altitude();
121+
122+
if constexpr (sensor_option == GPSSensorOption::WithCovariance)
123+
{
124+
message.position_covariance = get_covariance();
125+
}
126+
127+
return true;
128+
}
129+
130+
private:
131+
std::array<double, 9> covariance_{{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
132+
};
133+
134+
} // namespace semantic_components
135+
136+
#endif // SEMANTIC_COMPONENTS__GPS_SENSOR_HPP_

controller_interface/test/test_controller_with_options.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
#include <gtest/gtest.h>
1818
#include <string>
19-
#include "ament_index_cpp/get_package_prefix.hpp"
2019

2120
class FriendControllerWithOptions : public controller_with_options::ControllerWithOptions
2221
{
@@ -95,8 +94,8 @@ TEST(ControllerWithOption, init_with_node_options_arguments_parameters_file)
9594
rclcpp::init(argc, argv);
9695
// creates the controller
9796
FriendControllerWithOptions controller;
98-
const std::string params_file_path = ament_index_cpp::get_package_prefix("controller_interface") +
99-
"/test/test_controller_node_options.yaml";
97+
const std::string params_file_path =
98+
std::string(PARAMETERS_FILE_PATH) + std::string("test_controller_node_options.yaml");
10099
std::cerr << params_file_path << std::endl;
101100
auto controller_node_options = controller.define_custom_node_options();
102101
controller_node_options.arguments({"--ros-args", "--params-file", params_file_path});
@@ -129,8 +128,8 @@ TEST(
129128
rclcpp::init(argc, argv);
130129
// creates the controller
131130
FriendControllerWithOptions controller;
132-
const std::string params_file_path = ament_index_cpp::get_package_prefix("controller_interface") +
133-
"/test/test_controller_node_options.yaml";
131+
const std::string params_file_path =
132+
std::string(PARAMETERS_FILE_PATH) + std::string("test_controller_node_options.yaml");
134133
std::cerr << params_file_path << std::endl;
135134
auto controller_node_options = controller.define_custom_node_options();
136135
controller_node_options.arguments(

0 commit comments

Comments
 (0)