AutoAPMS
Resilient Robot Mission Management
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 "auto_apms_util/action_context.hpp"
18#include "px4_ros2/components/mode.hpp"
19#include "px4_ros2/odometry/attitude.hpp"
20#include "px4_ros2/odometry/global_position.hpp"
21#include "px4_ros2/odometry/local_position.hpp"
22#include "px4_ros2/utils/geodesic.hpp"
23#include "px4_ros2/utils/geometry.hpp"
24
26{
27
38template <class ActionT>
39class ModeBase : public px4_ros2::ModeBase
40{
41protected:
42 using ActionContextType = auto_apms_util::ActionContext<ActionT>;
43 using Goal = typename ActionContextType::Goal;
44 using Result = typename ActionContextType::Result;
45 using Feedback = typename ActionContextType::Feedback;
46
47 ModeBase(
48 rclcpp::Node & node, const Settings & settings, const std::string & topic_namespace_prefix,
49 std::shared_ptr<ActionContextType> action_context_ptr)
50 : px4_ros2::ModeBase{node, settings, topic_namespace_prefix}, action_context_ptr_{action_context_ptr}
51 {
52 }
53
54private:
55 virtual void OnActivateWithGoal(std::shared_ptr<const Goal> goal_ptr);
56 virtual void UpdateSetpointWithGoal(
57 float dt_s, std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
58 std::shared_ptr<Result> result_ptr) = 0;
59 virtual void onDeactivate() override {}
60
61 void onActivate() override;
62 void updateSetpoint(float dt_s) override;
63
64 const std::shared_ptr<ActionContextType> action_context_ptr_;
65};
66
67template <class ActionT>
68void ModeBase<ActionT>::OnActivateWithGoal(std::shared_ptr<const Goal> goal_ptr)
69{
70 (void)goal_ptr;
71}
72
73template <class ActionT>
74void ModeBase<ActionT>::onActivate()
75{
76 OnActivateWithGoal(action_context_ptr_->getGoalHandlePtr()->get_goal());
77}
78
79template <class ActionT>
80void ModeBase<ActionT>::updateSetpoint(float dt_s)
81{
82 UpdateSetpointWithGoal(
83 dt_s, action_context_ptr_->getGoalHandlePtr()->get_goal(), action_context_ptr_->getFeedbackPtr(),
84 action_context_ptr_->getResultPtr());
85}
86
87template <class ActionT>
88class PositionAwareMode : public ModeBase<ActionT>
89{
90protected:
91 using typename ModeBase<ActionT>::ActionContextType;
92
93 PositionAwareMode(
94 rclcpp::Node & node, const px4_ros2::ModeBase::Settings & settings, const std::string & topic_namespace_prefix,
95 std::shared_ptr<ActionContextType> action_context_ptr)
96 : ModeBase<ActionT>{node, settings, topic_namespace_prefix, action_context_ptr}
97 {
98 vehicle_global_position_ptr_ = std::make_shared<px4_ros2::OdometryGlobalPosition>(*this);
99 vehicle_local_position_ptr_ = std::make_shared<px4_ros2::OdometryLocalPosition>(*this);
100 vehicle_attitude_ptr_ = std::make_shared<px4_ros2::OdometryAttitude>(*this);
101 }
102
103 bool IsPositionReached(const Eigen::Vector3d & target_position_f_glob) const;
104 bool IsAltitudeReached(float target_altitude_amsl_m) const;
105 bool IsHeadingReached(float target_heading_rad) const;
106
107protected:
108 std::shared_ptr<px4_ros2::OdometryGlobalPosition> vehicle_global_position_ptr_;
109 std::shared_ptr<px4_ros2::OdometryLocalPosition> vehicle_local_position_ptr_;
110 std::shared_ptr<px4_ros2::OdometryAttitude> vehicle_attitude_ptr_;
111};
112
113template <class ActionT>
114bool PositionAwareMode<ActionT>::IsPositionReached(const Eigen::Vector3d & target_position_f_glob) const
115{
116 static constexpr float kPositionErrorThresholdMeter = 0.5f; // [m]
117 static constexpr float kVelocityErrorThresholdMeterPerSecond = 0.3f; // [m/s]
118 const float position_error_m =
119 px4_ros2::distanceToGlobalPosition(vehicle_global_position_ptr_->position(), target_position_f_glob);
120 return (position_error_m < kPositionErrorThresholdMeter) &&
121 (vehicle_local_position_ptr_->velocityNed().norm() < kVelocityErrorThresholdMeterPerSecond);
122}
123
124template <class ActionT>
125bool PositionAwareMode<ActionT>::IsAltitudeReached(float target_altitude_amsl_m) const
126{
127 auto target_position_f_glob = vehicle_global_position_ptr_->position();
128 target_position_f_glob.z() = target_altitude_amsl_m;
129 return IsPositionReached(target_position_f_glob);
130}
131
132template <class ActionT>
133bool PositionAwareMode<ActionT>::IsHeadingReached(float target_heading_rad) const
134{
135 using namespace px4_ros2::literals;
136 static constexpr float kHeadingErrorThresholdRad = 7.0_deg;
137 const float heading_error_wrapped = px4_ros2::wrapPi(target_heading_rad - vehicle_attitude_ptr_->yaw());
138 return fabsf(heading_error_wrapped) < kHeadingErrorThresholdRad;
139}
140
141} // namespace auto_apms_px4
Generic template class for a custom PX4 mode.
Definition mode.hpp:40
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:26