AutoAPMS
Streamlining behaviors in ROS 2
Loading...
Searching...
No Matches
has_parameter.cpp
1// Copyright 2024 Robin Müller
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// https://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#include <optional>
16#include <type_traits>
17
18#include "auto_apms_behavior_tree_core/node.hpp"
19#include "auto_apms_util/container.hpp"
20#include "rcl_interfaces/srv/list_parameters.hpp"
21
22#define INPUT_KEY_PARAM_NAME "parameter"
23#define INPUT_KEY_NODE_NAME "node"
24
26{
27
28class HasParameter : public core::RosServiceNode<rcl_interfaces::srv::ListParameters>
29{
30public:
31 HasParameter(const std::string & instance_name, const Config & config, const Context & context)
32 : RosServiceNode(instance_name, config, context)
33 {
34 // If input port is empty or not provided, refer to this ROS 2 node as the target
35 std::string node_name = context_.getFullyQualifiedRosNodeName();
36 if (
37 config.input_ports.find(INPUT_KEY_NODE_NAME) != config.input_ports.end() &&
38 !config.input_ports.at(INPUT_KEY_NODE_NAME).empty()) {
39 node_name = config.input_ports.at(INPUT_KEY_NODE_NAME);
40 }
41 createClient(node_name + "/list_parameters");
42 }
43
44 static BT::PortsList providedPorts()
45 {
46 // We do not use the default port for the service name
47 return {
48 BT::InputPort<std::string>(
49 INPUT_KEY_NODE_NAME, "Name of the targeted ROS 2 node. Leave empty to target this executor's node."),
50 BT::InputPort<std::string>(INPUT_KEY_PARAM_NAME, "Name of the parameter.")};
51 }
52
53 bool setRequest(Request::SharedPtr & request) override final
54 {
55 const BT::Expected<std::string> expected_name = getInput<std::string>(INPUT_KEY_PARAM_NAME);
56 if (!expected_name || expected_name.value().empty()) {
57 RCLCPP_ERROR(
58 logger_, "%s - Parameter name must not be empty.", context_.getFullyQualifiedTreeNodeName(this).c_str());
59 RCLCPP_DEBUG_EXPRESSION(
60 logger_, !expected_name, "%s - Error message: %s", context_.getFullyQualifiedTreeNodeName(this).c_str(),
61 expected_name.error().c_str());
62 return false;
63 }
64 has_parameter_name_ = expected_name.value();
65 request->depth = Request::DEPTH_RECURSIVE;
66 request->prefixes = {};
67 return true;
68 }
69
70 BT::NodeStatus onResponseReceived(const Response::SharedPtr & response) override final
71 {
72 if (auto_apms_util::contains(response->result.names, has_parameter_name_)) return BT::NodeStatus::SUCCESS;
73 return BT::NodeStatus::FAILURE;
74 }
75
76private:
77 std::string has_parameter_name_;
78};
79
80} // namespace auto_apms_behavior_tree
81
82AUTO_APMS_BEHAVIOR_TREE_REGISTER_NODE(auto_apms_behavior_tree::HasParameter)
Generic behavior tree node wrapper for a ROS 2 service client.
RosServiceNode(const std::string &instance_name, const Config &config, Context context)
#define AUTO_APMS_BEHAVIOR_TREE_REGISTER_NODE(type)
Macro for registering a behavior tree node plugin.
Definition node.hpp:44
bool contains(const ContainerT< ValueT, AllocatorT > &c, const ValueT &val)
Check whether a particular container structure contains a value.
Definition container.hpp:36
Powerful tooling for incorporating behavior trees for task development.
Definition behavior.hpp:32