AutoAPMS
Streamlining behaviors in ROS 2
Loading...
Searching...
No Matches
check_mode_completed.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// 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#include <cstdint>
16#include <memory>
17
18#include "auto_apms_behavior_tree_core/node.hpp"
19#include "px4_msgs/msg/mode_completed.hpp"
20#include "px4_ros2/utils/message_version.hpp"
21
22#define INPUT_KEY_NAV_STATE "nav_state"
23
24namespace auto_apms_px4
25{
26
42class CheckModeCompleted : public auto_apms_behavior_tree::core::RosSubscriberNode<px4_msgs::msg::ModeCompleted>
43{
44public:
45 CheckModeCompleted(
46 const std::string & instance_name, const BT::NodeConfig & config,
48 : RosSubscriberNode{instance_name, config, context, rclcpp::SensorDataQoS{}}
49 {
50 // Resolve the topic's message version suffix at runtime from the message definition, rather than baking it into
51 // the node manifest at configure time. Since the manifest does not fix a topic, the base class cannot resolve one
52 // at construction and defers creation to this constructor.
53 createSubscriber("fmu/out/mode_completed" + px4_ros2::getMessageNameVersion<px4_msgs::msg::ModeCompleted>());
54 }
55
56 static BT::PortsList providedPorts()
57 {
58 return providedBasicPorts({
59 BT::InputPort<int>(INPUT_KEY_NAV_STATE, "PX4 navigation state (mode id) whose completion is awaited."),
60 });
61 }
62
63 BT::NodeStatus onTick(const std::shared_ptr<px4_msgs::msg::ModeCompleted> & last_msg_ptr) final
64 {
65 // No completion message delivered on this tick - keep waiting (the one-shot message is buffered by the base class
66 // and delivered on the tick following its arrival).
67 if (!last_msg_ptr) return BT::NodeStatus::FAILURE;
68
69 const BT::Expected<int> expected_nav_state = getInput<int>(INPUT_KEY_NAV_STATE);
70 if (!expected_nav_state) {
71 RCLCPP_ERROR(
72 logger_, "%s - Missing required input '%s': %s", context_.getFullyQualifiedTreeNodeName(this).c_str(),
73 INPUT_KEY_NAV_STATE, expected_nav_state.error().c_str());
74 return BT::NodeStatus::FAILURE;
75 }
76
77 // A completion for a different mode is irrelevant - keep waiting for ours.
78 if (last_msg_ptr->nav_state != static_cast<uint8_t>(expected_nav_state.value())) return BT::NodeStatus::FAILURE;
79
80 if (last_msg_ptr->result != px4_msgs::msg::ModeCompleted::RESULT_SUCCESS) {
81 RCLCPP_WARN(
82 logger_, "%s - Mode nav_state %d reported completion with non-success result %u.",
83 context_.getFullyQualifiedTreeNodeName(this).c_str(), expected_nav_state.value(), last_msg_ptr->result);
84 return BT::NodeStatus::FAILURE;
85 }
86
87 return BT::NodeStatus::SUCCESS;
88 }
89};
90
91} // namespace auto_apms_px4
92
Additional parameters specific to ROS 2 determined at runtime by TreeBuilder.
Generic behavior tree node wrapper for a ROS 2 subscriber.
RosSubscriberNode(const std::string &instance_name, const Config &config, Context context, const rclcpp::QoS &qos={10})
Condition node that succeeds once the mode with the expected nav_state reports successful completion.
#define AUTO_APMS_BEHAVIOR_TREE_REGISTER_NODE(type)
Macro for registering a behavior tree node plugin.
Definition node.hpp:50
Implementation of PX4 mode peers offered by px4_ros2_cpp enabling integration with AutoAPMS.