Skip to content

Commit 8abcdb0

Browse files
broadcaster for magnetic field values from a magnetometer
1 parent 8fc0377 commit 8abcdb0

File tree

6 files changed

+286
-0
lines changed

6 files changed

+286
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
project(magnetometer_broadcaster)
3+
4+
find_package(ros2_control_cmake REQUIRED)
5+
set_compiler_options()
6+
export_windows_symbols()
7+
8+
set(THIS_PACKAGE_INCLUDE_DEPENDS
9+
controller_interface
10+
generate_parameter_library
11+
hardware_interface
12+
pluginlib
13+
rclcpp
14+
rclcpp_lifecycle
15+
realtime_tools
16+
sensor_msgs
17+
)
18+
19+
find_package(ament_cmake REQUIRED)
20+
find_package(backward_ros REQUIRED)
21+
foreach(Dependency IN ITEMS ${THIS_PACKAGE_INCLUDE_DEPENDS})
22+
find_package(${Dependency} REQUIRED)
23+
endforeach()
24+
25+
generate_parameter_library(magnetometer_broadcaster_parameters
26+
src/magnetometer_broadcaster_parameters.yaml
27+
)
28+
29+
add_library(magnetometer_broadcaster SHARED
30+
src/magnetometer_broadcaster.cpp
31+
)
32+
target_compile_features(magnetometer_broadcaster PUBLIC cxx_std_20)
33+
target_link_libraries(magnetometer_broadcaster PUBLIC
34+
magnetometer_broadcaster_parameters
35+
controller_interface::controller_interface
36+
hardware_interface::hardware_interface
37+
pluginlib::pluginlib
38+
rclcpp::rclcpp
39+
rclcpp_lifecycle::rclcpp_lifecycle
40+
realtime_tools::realtime_tools
41+
${sensor_msgs_TARGETS})
42+
43+
pluginlib_export_plugin_description_file(
44+
controller_interface magnetometer_broadcaster.xml)
45+
46+
install(
47+
TARGETS
48+
magnetometer_broadcaster
49+
magnetometer_broadcaster_parameters
50+
EXPORT export_magnetometer_broadcaster
51+
RUNTIME DESTINATION bin
52+
ARCHIVE DESTINATION lib
53+
LIBRARY DESTINATION lib
54+
)
55+
56+
ament_export_targets(export_magnetometer_broadcaster HAS_LIBRARY_TARGET)
57+
ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS})
58+
ament_package()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<library path="magnetometer_broadcaster">
2+
<class name="magnetometer_broadcaster/MagnetometerBroadcaster"
3+
type="magnetometer_broadcaster::MagnetometerBroadcaster"
4+
base_class_type="controller_interface::ControllerInterface"
5+
>
6+
<description>
7+
This controller publishes the readings of a magnetometer as sensor_msgs/msg/MagneticField message.
8+
</description>
9+
</class>
10+
</library>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd"
3+
schematypens="http://www.w3.org/2001/XMLSchema"
4+
?>
5+
<package format="3">
6+
<name>magnetometer_broadcaster</name>
7+
<version>6.4.0</version>
8+
<description>Controller to publish readings of a magnetometer.</description>
9+
10+
<maintainer email="bence.magyar.robotics@gmail.com">Bence Magyar</maintainer>
11+
<maintainer email="denis@stoglrobotics.de">Denis Štogl</maintainer>
12+
<maintainer email="christoph.froehlich@ait.ac.at">Christoph Froehlich</maintainer>
13+
<maintainer email="sai.kishor@pal-robotics.com">Sai Kishor Kothakota</maintainer>
14+
15+
<license>Apache License 2.0</license>
16+
17+
<url type="website">https://control.ros.org</url>
18+
<url type="bugtracker">https://github.com/ros-controls/ros2_controllers/issues</url>
19+
<url type="repository">https://github.com/ros-controls/ros2_controllers/</url>
20+
21+
<author email="Rauch.Christian@gmx.de">Christian Rauch</author>
22+
23+
<buildtool_depend>ament_cmake</buildtool_depend>
24+
25+
<build_depend>ros2_control_cmake</build_depend>
26+
27+
<depend>backward_ros</depend>
28+
<depend>controller_interface</depend>
29+
<depend>eigen</depend>
30+
<depend>generate_parameter_library</depend>
31+
<depend>hardware_interface</depend>
32+
<depend>pluginlib</depend>
33+
<depend>rclcpp</depend>
34+
<depend>rclcpp_lifecycle</depend>
35+
<depend>realtime_tools</depend>
36+
<depend>sensor_msgs</depend>
37+
38+
<export>
39+
<build_type>ament_cmake</build_type>
40+
</export>
41+
</package>
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// Copyright 2026 Christian Rauch
2+
// Copyright 2021 PAL Robotics SL.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
/*
17+
* Authors: Christian Rauch, Subhas Das, Denis Stogl, Victor Lopez
18+
*/
19+
20+
#include <memory>
21+
#include <vector>
22+
23+
#include <controller_interface/controller_interface.hpp>
24+
#include <magnetometer_broadcaster/magnetometer_broadcaster_parameters.hpp>
25+
#include <pluginlib/class_list_macros.hpp>
26+
#include <rclcpp_lifecycle/state.hpp>
27+
#include <realtime_tools/realtime_publisher.hpp>
28+
#include <semantic_components/magnetic_field_sensor.hpp>
29+
#include <sensor_msgs/msg/magnetic_field.hpp>
30+
31+
namespace magnetometer_broadcaster
32+
{
33+
34+
class MagnetometerBroadcaster : public controller_interface::ControllerInterface
35+
{
36+
public:
37+
controller_interface::InterfaceConfiguration command_interface_configuration() const override
38+
{
39+
return {.type = controller_interface::interface_configuration_type::NONE};
40+
}
41+
42+
controller_interface::InterfaceConfiguration state_interface_configuration() const override
43+
{
44+
return {
45+
.type = controller_interface::interface_configuration_type::INDIVIDUAL,
46+
.names = magnetometer_->get_state_interface_names(),
47+
};
48+
}
49+
50+
controller_interface::CallbackReturn on_init() override
51+
{
52+
try
53+
{
54+
param_listener_ = std::make_shared<ParamListener>(get_node());
55+
}
56+
catch (const std::exception & e)
57+
{
58+
RCLCPP_ERROR_STREAM(
59+
get_node()->get_logger(), "Exception thrown during init stage with message: " << e.what());
60+
return CallbackReturn::ERROR;
61+
}
62+
63+
return CallbackReturn::SUCCESS;
64+
}
65+
66+
controller_interface::CallbackReturn on_configure(
67+
const rclcpp_lifecycle::State & /*previous_state*/) override
68+
{
69+
try
70+
{
71+
params_ = param_listener_->get_params();
72+
}
73+
catch (const std::exception & e)
74+
{
75+
RCLCPP_ERROR_STREAM(
76+
get_node()->get_logger(),
77+
"Exception thrown during config stage with message: " << e.what());
78+
return CallbackReturn::ERROR;
79+
}
80+
81+
magnetometer_ = std::make_unique<semantic_components::MagneticFieldSensor>(params_.sensor_name);
82+
try
83+
{
84+
sensor_state_publisher_ = get_node()->create_publisher<sensor_msgs::msg::MagneticField>(
85+
"~/magnetic_field", rclcpp::SystemDefaultsQoS());
86+
realtime_publisher_ = std::make_unique<StatePublisher>(sensor_state_publisher_);
87+
}
88+
catch (const std::exception & e)
89+
{
90+
RCLCPP_ERROR_STREAM(
91+
get_node()->get_logger(),
92+
"Exception thrown during publisher creation at configure stage with message: " << e.what());
93+
return CallbackReturn::ERROR;
94+
}
95+
96+
state_message_.header.frame_id = params_.frame_id;
97+
std::copy(
98+
params_.static_covariance.begin(), params_.static_covariance.end(),
99+
state_message_.magnetic_field_covariance.begin());
100+
101+
return CallbackReturn::SUCCESS;
102+
}
103+
104+
controller_interface::CallbackReturn on_activate(
105+
const rclcpp_lifecycle::State & /*previous_state*/) override
106+
{
107+
magnetometer_->assign_loaned_state_interfaces(state_interfaces_);
108+
return CallbackReturn::SUCCESS;
109+
}
110+
111+
controller_interface::CallbackReturn on_deactivate(
112+
const rclcpp_lifecycle::State & /*previous_state*/) override
113+
{
114+
magnetometer_->release_interfaces();
115+
return CallbackReturn::SUCCESS;
116+
}
117+
118+
controller_interface::return_type update(
119+
const rclcpp::Time & time, const rclcpp::Duration & /*period*/) override
120+
{
121+
magnetometer_->get_values_as_message(state_message_);
122+
123+
if (realtime_publisher_)
124+
{
125+
state_message_.header.stamp = time;
126+
realtime_publisher_->try_publish(state_message_);
127+
}
128+
129+
return controller_interface::return_type::OK;
130+
}
131+
132+
protected:
133+
std::shared_ptr<ParamListener> param_listener_;
134+
Params params_;
135+
136+
std::unique_ptr<semantic_components::MagneticFieldSensor> magnetometer_;
137+
138+
using StatePublisher = realtime_tools::RealtimePublisher<sensor_msgs::msg::MagneticField>;
139+
rclcpp::Publisher<sensor_msgs::msg::MagneticField>::SharedPtr sensor_state_publisher_;
140+
std::unique_ptr<StatePublisher> realtime_publisher_;
141+
sensor_msgs::msg::MagneticField state_message_;
142+
};
143+
144+
} // namespace magnetometer_broadcaster
145+
146+
PLUGINLIB_EXPORT_CLASS(
147+
magnetometer_broadcaster::MagnetometerBroadcaster, controller_interface::ControllerInterface)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
magnetometer_broadcaster:
2+
sensor_name: {
3+
type: string,
4+
default_value: "",
5+
read_only: true,
6+
description: "Defines sensor name used as prefix for its interfaces.
7+
Interface names are: ``<sensor_name>/magnetic_field.x, <sensor_name>/magnetic_field.x, <sensor_name>/magnetic_field.z.``",
8+
validation: {
9+
not_empty<>: null
10+
}
11+
}
12+
frame_id: {
13+
type: string,
14+
default_value: "",
15+
read_only: true,
16+
description: "Sensor's frame_id in which values are published.",
17+
validation: {
18+
not_empty<>: null
19+
}
20+
}
21+
static_covariance: {
22+
type: double_array,
23+
default_value: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
24+
read_only: true,
25+
description: "Static covariance. Row major about x, y, z axes",
26+
validation: {
27+
fixed_size<>: [9],
28+
}
29+
}

ros2_controllers/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<exec_depend>imu_sensor_broadcaster</exec_depend>
3131
<exec_depend>joint_state_broadcaster</exec_depend>
3232
<exec_depend>joint_trajectory_controller</exec_depend>
33+
<exec_depend>magnetometer_broadcaster</exec_depend>
3334
<exec_depend>mecanum_drive_controller</exec_depend>
3435
<exec_depend>motion_primitives_controllers</exec_depend>
3536
<exec_depend>omni_wheel_drive_controller</exec_depend>

0 commit comments

Comments
 (0)