9 const std::string& description,
10 const bool add_to_auto_reconfigurable_params,
11 const bool is_required,
13 const std::optional<double>& from_value,
14 const std::optional<double>& to_value,
15 const std::optional<double>& step_value,
16 const std::string& additional_constraints) {
17 rcl_interfaces::msg::ParameterDescriptor param_desc;
18 param_desc.description = description;
19 param_desc.additional_constraints = additional_constraints;
20 param_desc.read_only = read_only;
22 auto type = rclcpp::ParameterValue(param).get_type();
24 if (from_value.has_value() && to_value.has_value()) {
25 if constexpr (std::is_integral_v<T>) {
26 rcl_interfaces::msg::IntegerRange range;
27 T step =
static_cast<T
>(step_value.has_value() ? step_value.value() : 1);
28 range.set__from_value(
static_cast<T
>(from_value.value())).set__to_value(
static_cast<T
>(to_value.value())).set__step(step);
29 param_desc.integer_range = {range};
30 }
else if constexpr (std::is_floating_point_v<T>) {
31 rcl_interfaces::msg::FloatingPointRange range;
32 T step =
static_cast<T
>(step_value.has_value() ? step_value.value() : 1.0);
33 range.set__from_value(
static_cast<T
>(from_value.value())).set__to_value(
static_cast<T
>(to_value.value())).set__step(step);
34 param_desc.floating_point_range = {range};
36 RCLCPP_WARN(this->get_logger(),
"Parameter type of parameter '%s' does not support specifying a range", name.c_str());
40 this->declare_parameter(name, type, param_desc);
43 param = this->get_parameter(name).get_value<T>();
45 ss <<
"Loaded parameter '" << name <<
"': ";
48 for (
const auto& element : param) ss << element << (&element != ¶m.back() ?
", " :
"");
53 RCLCPP_INFO_STREAM(this->get_logger(), ss.str());
54 }
catch (rclcpp::exceptions::ParameterUninitializedException&) {
56 RCLCPP_FATAL_STREAM(this->get_logger(),
"Missing required parameter '" << name <<
"', exiting");
60 ss <<
"Missing parameter '" << name <<
"', using default value: ";
63 for (
const auto& element : param) ss << element << (&element != ¶m.back() ?
", " :
"");
68 RCLCPP_WARN_STREAM(this->get_logger(), ss.str());
69 this->set_parameters({rclcpp::Parameter(name, rclcpp::ParameterValue(param))});
73 if (add_to_auto_reconfigurable_params) {
74 std::function<void(
const rclcpp::Parameter&)> setter = [¶m](
const rclcpp::Parameter& p) { param = p.get_value<T>(); };
80 rcl_interfaces::msg::SetParametersResult result;
81 result.successful =
false;
83 for (
const auto& param : parameters) {
85 if (param.get_name() ==
"a_decel") {
86 if (param.as_double() >= 0.0) {
87 result.successful =
false;
88 result.reason =
"a_decel (" + std::to_string(param.as_double()) +
") must be < 0.0";
89 RCLCPP_WARN(this->get_logger(),
"Rejected parameter change for 'a_decel': %s", result.reason.c_str());
92 result.successful =
false;
94 "a_max_decel (" + std::to_string(
a_max_decel_) +
") must be <= a_decel (" + std::to_string(param.as_double()) +
")";
95 RCLCPP_WARN(this->get_logger(),
"Rejected parameter change for 'a_decel': %s", result.reason.c_str());
98 }
else if (param.get_name() ==
"a_max_decel") {
99 if (param.as_double() >= 0.0) {
100 result.successful =
false;
101 result.reason =
"a_max_decel (" + std::to_string(param.as_double()) +
") must be < 0.0";
102 RCLCPP_WARN(this->get_logger(),
"Rejected parameter change for 'a_max_decel': %s", result.reason.c_str());
104 }
else if (param.as_double() >
a_decel_) {
105 result.successful =
false;
107 "a_max_decel (" + std::to_string(param.as_double()) +
") must be <= a_decel (" + std::to_string(
a_decel_) +
")";
108 RCLCPP_WARN(this->get_logger(),
"Rejected parameter change for 'a_max_decel': %s", result.reason.c_str());
115 if (param.get_name() == std::get<0>(auto_reconfigurable_param)) {
116 std::get<1>(auto_reconfigurable_param)(param);
117 RCLCPP_INFO(this->get_logger(),
"Reconfigured parameter '%s'", param.get_name().c_str());
118 result.successful =
true;
142 transformed_path.
header = target_header;
144 if (path.
points.empty()) {
145 return transformed_path;
151 geometry_msgs::msg::TransformStamped tf;
153 tf =
tf2_buffer_->lookupTransform(target_header.frame_id, target_header.stamp, path.
header.frame_id, path.
header.stamp,
155 for (
const auto& point : path.
points) {
156 geometry_msgs::msg::PointStamped point_msg, transformed_point_msg;
157 point_msg.header = path.
header;
158 point_msg.point.x = point.position.x();
159 point_msg.point.y = point.position.y();
160 point_msg.point.z = 0.0;
161 tf2::doTransform(point_msg, transformed_point_msg, tf);
163 transformed_point.
position = Eigen::Vector2d(transformed_point_msg.point.x, transformed_point_msg.point.y);
164 transformed_path.
points.push_back(transformed_point);
166 }
catch (tf2::TransformException& ex) {
167 RCLCPP_WARN(this->get_logger(),
"Could not transform path: %s. Returning an empty path.", ex.what());
170 return transformed_path;
void declareAndLoadParameter(const std::string &name, T ¶m, const std::string &description, const bool add_to_auto_reconfigurable_params=true, const bool is_required=false, const bool read_only=false, const std::optional< double > &from_value=std::nullopt, const std::optional< double > &to_value=std::nullopt, const std::optional< double > &step_value=std::nullopt, const std::string &additional_constraints="")
Declares a ROS parameter, loads its value and optionally registers it for runtime updates.