AutoAPMS
Streamlining behaviors in ROS 2
Loading...
Searching...
No Matches
mode.hpp
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#pragma once
16
17#include <Eigen/Geometry>
18
19#include "auto_apms_util/action_context.hpp"
20#include "px4_ros2/components/mode.hpp"
21#include "px4_ros2/odometry/attitude.hpp"
22#include "px4_ros2/odometry/global_position.hpp"
23#include "px4_ros2/odometry/local_position.hpp"
24#include "px4_ros2/utils/geodesic.hpp"
25#include "px4_ros2/utils/geometry.hpp"
26
28{
29
40template <class ActionT>
41class ModeBase : public px4_ros2::ModeBase
42{
43protected:
44 using ActionContextType = auto_apms_util::ActionContext<ActionT>;
45 using Goal = typename ActionContextType::Goal;
46 using Result = typename ActionContextType::Result;
47 using Feedback = typename ActionContextType::Feedback;
48
49 ModeBase(rclcpp::Node & node, Settings settings, std::shared_ptr<ActionContextType> action_context_ptr)
50 : px4_ros2::ModeBase{node, settings}, action_context_ptr_{action_context_ptr}
51 {
52 }
53
54private:
55 /* Virtual methods */
56
57 virtual void onActivateWithGoal(std::shared_ptr<const Goal> goal_ptr);
58 virtual void onDeactivateWithGoal(std::shared_ptr<const Goal> goal_ptr);
59
64
66 float dt_s, std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
67 std::shared_ptr<Result> result_ptr) = 0;
68 virtual void updateSetpointOnCancel(
69 float dt_s, std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
70 std::shared_ptr<Result> result_ptr);
71
72 /* Overridden base methods */
73
74 void onDeactivate() override final;
75 void onActivate() override final;
76 void updateSetpoint(float dt_s) override;
77
78 const std::shared_ptr<ActionContextType> action_context_ptr_;
79};
80
81template <class ActionT>
82void ModeBase<ActionT>::onActivateWithGoal(std::shared_ptr<const Goal> /*goal_ptr*/)
83{
84}
85
86template <class ActionT>
87void ModeBase<ActionT>::onDeactivateWithGoal(std::shared_ptr<const Goal> /*goal_ptr*/)
88{
89}
90
91template <class ActionT>
92void ModeBase<ActionT>::updateSetpointOnCancel(
93 float /*dt_s*/, std::shared_ptr<const Goal> /*goal_ptr*/, std::shared_ptr<Feedback> /*feedback_ptr*/,
94 std::shared_ptr<Result> /*result_ptr*/)
95{
96 completed(px4_ros2::Result::Interrupted);
97}
98
99template <class ActionT>
100void ModeBase<ActionT>::onActivate()
101{
102 onActivateWithGoal(action_context_ptr_->getGoalHandlePtr()->get_goal());
103}
104
105template <class ActionT>
106void ModeBase<ActionT>::onDeactivate()
107{
108 const auto goal_handle_ptr = action_context_ptr_->getGoalHandlePtr();
109 onDeactivateWithGoal(goal_handle_ptr ? goal_handle_ptr->get_goal() : nullptr);
110}
111
112template <class ActionT>
113void ModeBase<ActionT>::updateSetpoint(float dt_s)
114{
115 if (action_context_ptr_->isValid()) {
116 const auto goal_handle_ptr = action_context_ptr_->getGoalHandlePtr();
117 if (goal_handle_ptr->is_canceling()) {
118 updateSetpointOnCancel(
119 dt_s, goal_handle_ptr->get_goal(), action_context_ptr_->getFeedbackPtr(), action_context_ptr_->getResultPtr());
120 } else {
122 dt_s, goal_handle_ptr->get_goal(), action_context_ptr_->getFeedbackPtr(), action_context_ptr_->getResultPtr());
123 }
124 }
125}
126
127template <class ActionT>
128class PositionAwareMode : public ModeBase<ActionT>
129{
130protected:
131 using typename ModeBase<ActionT>::ActionContextType;
132
133 PositionAwareMode(
134 rclcpp::Node & node, px4_ros2::ModeBase::Settings settings, std::shared_ptr<ActionContextType> action_context_ptr)
135 : ModeBase<ActionT>{node, settings, action_context_ptr}
136 {
137 vehicle_global_position_ptr_ = std::make_shared<px4_ros2::OdometryGlobalPosition>(*this);
138 vehicle_local_position_ptr_ = std::make_shared<px4_ros2::OdometryLocalPosition>(*this);
139 vehicle_attitude_ptr_ = std::make_shared<px4_ros2::OdometryAttitude>(*this);
140 }
141
142 bool isGlobalPositionReached(
143 const Eigen::Vector3d & target_position_f_glob, double reached_thresh_pos_m = 0.5,
144 double reached_thresh_vel_m_s = 0.3) const;
145
146 bool isLocalPositionReached(
147 const Eigen::Vector3d & target_position_f_ned, double reached_thresh_pos_m = 0.5,
148 double reached_thresh_vel_m_s = 0.3) const;
149
150 bool isGlobalAltitudeReached(
151 float target_altitude_amsl_m, double reached_thresh_pos_m = 0.5, double reached_thresh_vel_m_s = 0.3) const;
152
153 bool isLocalAltitudeReached(
154 float target_altitude_hagl_m, double reached_thresh_pos_m = 0.5, double reached_thresh_vel_m_s = 0.3) const;
155
156 bool isHeadingReached(float target_heading_rad, double reached_thresh_heading_rad = 0.12) const;
157
158protected:
159 std::shared_ptr<px4_ros2::OdometryGlobalPosition> vehicle_global_position_ptr_;
160 std::shared_ptr<px4_ros2::OdometryLocalPosition> vehicle_local_position_ptr_;
161 std::shared_ptr<px4_ros2::OdometryAttitude> vehicle_attitude_ptr_;
162};
163
164template <class ActionT>
165bool PositionAwareMode<ActionT>::isGlobalPositionReached(
166 const Eigen::Vector3d & target_position_f_glob, double reached_thresh_pos_m, double reached_thresh_vel_m_s) const
167{
168 const float position_error_m =
169 px4_ros2::distanceToGlobalPosition(vehicle_global_position_ptr_->position(), target_position_f_glob);
170 return (position_error_m < reached_thresh_pos_m) &&
171 (vehicle_local_position_ptr_->velocityNed().norm() <= reached_thresh_vel_m_s);
172}
173
174template <class ActionT>
175bool PositionAwareMode<ActionT>::isLocalPositionReached(
176 const Eigen::Vector3d & target_position_f_ned, double reached_thresh_pos_m, double reached_thresh_vel_m_s) const
177{
178 const px4_msgs::msg::VehicleLocalPosition & pos = vehicle_local_position_ptr_->last();
179 const Eigen::Vector3d vec(pos.x, pos.y, pos.z);
180 const double position_error_m = (target_position_f_ned - vec).norm();
181 return (position_error_m < reached_thresh_pos_m) &&
182 (vehicle_local_position_ptr_->velocityNed().norm() <= reached_thresh_vel_m_s);
183}
184
185template <class ActionT>
186bool PositionAwareMode<ActionT>::isGlobalAltitudeReached(
187 float target_altitude_amsl_m, double reached_thresh_pos_m, double reached_thresh_vel_m_s) const
188{
189 Eigen::Vector3d target_position_f_glob = vehicle_global_position_ptr_->position();
190 target_position_f_glob.z() = target_altitude_amsl_m;
191 return isGlobalPositionReached(target_position_f_glob, reached_thresh_pos_m, reached_thresh_vel_m_s);
192}
193
194template <class ActionT>
195bool PositionAwareMode<ActionT>::isLocalAltitudeReached(
196 float target_altitude_hagl_m, double reached_thresh_pos_m, double reached_thresh_vel_m_s) const
197{
198 const px4_msgs::msg::VehicleLocalPosition & pos = vehicle_local_position_ptr_->last();
199 const Eigen::Vector3d target_position_f_ned(pos.x, pos.y, target_altitude_hagl_m);
200 return isLocalPositionReached(target_position_f_ned, reached_thresh_pos_m, reached_thresh_vel_m_s);
201}
202
203template <class ActionT>
204bool PositionAwareMode<ActionT>::isHeadingReached(float target_heading_rad, double reached_thresh_heading_rad) const
205{
206 const float heading_error_wrapped = px4_ros2::wrapPi(target_heading_rad - vehicle_attitude_ptr_->yaw());
207 return fabsf(heading_error_wrapped) <= fabsf(reached_thresh_heading_rad);
208}
209
210} // namespace auto_apms_px4
virtual void updateSetpointWithGoal(float dt_s, std::shared_ptr< const Goal > goal_ptr, std::shared_ptr< Feedback > feedback_ptr, std::shared_ptr< Result > result_ptr)=0
Helper class that stores contextual information related to a ROS 2 action.
Implementation of PX4 mode peers offered by px4_ros2_cpp enabling integration with AutoAPMS.
Definition mode.hpp:28