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// 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#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(
50 rclcpp::Node & node, const Settings & settings, const std::string & topic_namespace_prefix,
51 std::shared_ptr<ActionContextType> action_context_ptr)
52 : px4_ros2::ModeBase{node, settings, topic_namespace_prefix}, action_context_ptr_{action_context_ptr}
53 {
54 }
55
56private:
57 virtual void OnActivateWithGoal(std::shared_ptr<const Goal> goal_ptr);
58 virtual void UpdateSetpointWithGoal(
59 float dt_s, std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
60 std::shared_ptr<Result> result_ptr) = 0;
61 virtual void onDeactivate() override {}
62
63 void onActivate() override;
64 void updateSetpoint(float dt_s) override;
65
66 const std::shared_ptr<ActionContextType> action_context_ptr_;
67};
68
69template <class ActionT>
70void ModeBase<ActionT>::OnActivateWithGoal(std::shared_ptr<const Goal> goal_ptr)
71{
72 (void)goal_ptr;
73}
74
75template <class ActionT>
76void ModeBase<ActionT>::onActivate()
77{
78 OnActivateWithGoal(action_context_ptr_->getGoalHandlePtr()->get_goal());
79}
80
81template <class ActionT>
82void ModeBase<ActionT>::updateSetpoint(float dt_s)
83{
84 UpdateSetpointWithGoal(
85 dt_s, action_context_ptr_->getGoalHandlePtr()->get_goal(), action_context_ptr_->getFeedbackPtr(),
86 action_context_ptr_->getResultPtr());
87}
88
89template <class ActionT>
90class PositionAwareMode : public ModeBase<ActionT>
91{
92protected:
93 using typename ModeBase<ActionT>::ActionContextType;
94
95 PositionAwareMode(
96 rclcpp::Node & node, const px4_ros2::ModeBase::Settings & settings, const std::string & topic_namespace_prefix,
97 std::shared_ptr<ActionContextType> action_context_ptr)
98 : ModeBase<ActionT>{node, settings, topic_namespace_prefix, action_context_ptr}
99 {
100 vehicle_global_position_ptr_ = std::make_shared<px4_ros2::OdometryGlobalPosition>(*this);
101 vehicle_local_position_ptr_ = std::make_shared<px4_ros2::OdometryLocalPosition>(*this);
102 vehicle_attitude_ptr_ = std::make_shared<px4_ros2::OdometryAttitude>(*this);
103 }
104
105 bool IsGlobalPositionReached(
106 const Eigen::Vector3d & target_position_f_glob, double reached_thresh_pos_m = 0.5,
107 double reached_thresh_vel_m_s = 0.3) const;
108
109 bool IsLocalPositionReached(
110 const Eigen::Vector3d & target_position_f_ned, double reached_thresh_pos_m = 0.5,
111 double reached_thresh_vel_m_s = 0.3) const;
112
113 bool IsGlobalAltitudeReached(
114 float target_altitude_amsl_m, double reached_thresh_pos_m = 0.5, double reached_thresh_vel_m_s = 0.3) const;
115
116 bool IsLocalAltitudeReached(
117 float target_altitude_hagl_m, double reached_thresh_pos_m = 0.5, double reached_thresh_vel_m_s = 0.3) const;
118
119 bool IsHeadingReached(float target_heading_rad, double reached_thresh_heading_rad = 0.12) const;
120
121protected:
122 std::shared_ptr<px4_ros2::OdometryGlobalPosition> vehicle_global_position_ptr_;
123 std::shared_ptr<px4_ros2::OdometryLocalPosition> vehicle_local_position_ptr_;
124 std::shared_ptr<px4_ros2::OdometryAttitude> vehicle_attitude_ptr_;
125};
126
127template <class ActionT>
128bool PositionAwareMode<ActionT>::IsGlobalPositionReached(
129 const Eigen::Vector3d & target_position_f_glob, double reached_thresh_pos_m, double reached_thresh_vel_m_s) const
130{
131 const float position_error_m =
132 px4_ros2::distanceToGlobalPosition(vehicle_global_position_ptr_->position(), target_position_f_glob);
133 return (position_error_m < reached_thresh_pos_m) &&
134 (vehicle_local_position_ptr_->velocityNed().norm() <= reached_thresh_vel_m_s);
135}
136
137template <class ActionT>
138bool PositionAwareMode<ActionT>::IsLocalPositionReached(
139 const Eigen::Vector3d & target_position_f_ned, double reached_thresh_pos_m, double reached_thresh_vel_m_s) const
140{
141 const px4_msgs::msg::VehicleLocalPosition & pos = vehicle_local_position_ptr_->last();
142 const Eigen::Vector3d vec(pos.x, pos.y, pos.z);
143 const double position_error_m = (target_position_f_ned - vec).norm();
144 return (position_error_m < reached_thresh_pos_m) &&
145 (vehicle_local_position_ptr_->velocityNed().norm() <= reached_thresh_vel_m_s);
146}
147
148template <class ActionT>
149bool PositionAwareMode<ActionT>::IsGlobalAltitudeReached(
150 float target_altitude_amsl_m, double reached_thresh_pos_m, double reached_thresh_vel_m_s) const
151{
152 Eigen::Vector3d target_position_f_glob = vehicle_global_position_ptr_->position();
153 target_position_f_glob.z() = target_altitude_amsl_m;
154 return IsGlobalPositionReached(target_position_f_glob, reached_thresh_pos_m, reached_thresh_vel_m_s);
155}
156
157template <class ActionT>
158bool PositionAwareMode<ActionT>::IsLocalAltitudeReached(
159 float target_altitude_hagl_m, double reached_thresh_pos_m, double reached_thresh_vel_m_s) const
160{
161 const px4_msgs::msg::VehicleLocalPosition & pos = vehicle_local_position_ptr_->last();
162 const Eigen::Vector3d target_position_f_ned(pos.x, pos.y, target_altitude_hagl_m);
163 return IsLocalPositionReached(target_position_f_ned, reached_thresh_pos_m, reached_thresh_vel_m_s);
164}
165
166template <class ActionT>
167bool PositionAwareMode<ActionT>::IsHeadingReached(float target_heading_rad, double reached_thresh_heading_rad) const
168{
169 const float heading_error_wrapped = px4_ros2::wrapPi(target_heading_rad - vehicle_attitude_ptr_->yaw());
170 return fabsf(heading_error_wrapped) <= fabsf(reached_thresh_heading_rad);
171}
172
173} // namespace auto_apms_px4
Generic template class for a custom PX4 mode.
Definition mode.hpp:42
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