AutoAPMS
Resilient Robot Mission Management
Loading...
Searching...
No Matches
goto.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 "px4_ros2/control/setpoint_types/goto.hpp"
16
17#include <Eigen/Core>
18
19#include "auto_apms_interfaces/action/go_to.hpp"
20#include "auto_apms_px4/mode_executor.hpp"
21#include "px4_ros2/utils/geodesic.hpp"
22#include "tf2_eigen/tf2_eigen.hpp"
23
24namespace auto_apms_px4
25{
26
27using GoToActionType = auto_apms_interfaces::action::GoTo;
28
29class GoToMode : public PositionAwareMode<GoToActionType>
30{
31 std::shared_ptr<px4_ros2::GotoGlobalSetpointType> goto_setpoint_ptr_;
32 Eigen::Vector3d position_target_f_glob_;
33 float heading_target_rad_;
34
35public:
36 GoToMode(
37 rclcpp::Node & node, const px4_ros2::ModeBase::Settings & settings, const std::string & topic_namespace_prefix,
38 std::shared_ptr<ActionContextType> action_context_ptr)
39 : PositionAwareMode{node, settings, topic_namespace_prefix, action_context_ptr}
40 {
41 goto_setpoint_ptr_ = std::make_shared<px4_ros2::GotoGlobalSetpointType>(*this);
42 }
43
44private:
45 void OnActivateWithGoal(std::shared_ptr<const Goal> goal_ptr) final
46 {
47 position_target_f_glob_ = Eigen::Vector3d(goal_ptr->lat, goal_ptr->lon, goal_ptr->alt);
48
49 // Heading target has to be in rad clockwise from north
50 if (goal_ptr->head_towards_destination) {
51 // Heading target needs to be in interval [-pi, pi] (from north)
52 heading_target_rad_ =
53 px4_ros2::headingToGlobalPosition(vehicle_global_position_ptr_->position(), position_target_f_glob_);
54 } else {
55 heading_target_rad_ = goal_ptr->heading_clockwise_from_north_rad;
56 }
57
58 auto double_to_string = [](double num, int decimals) {
59 std::stringstream stream;
60 stream << std::fixed << std::setprecision(decimals) << num;
61 return stream.str();
62 };
63
64 RCLCPP_DEBUG(
65 node().get_logger(), "GoTo target: Position: [%s°, %s°, %sm] - Heading: %f",
66 double_to_string(position_target_f_glob_.x(), 10).c_str(),
67 double_to_string(position_target_f_glob_.y(), 10).c_str(),
68 double_to_string(position_target_f_glob_.z(), 2).c_str(), heading_target_rad_);
69 }
70 void UpdateSetpointWithGoal(
71 float dt_s, std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
72 std::shared_ptr<Result> result_ptr) final
73 {
74 (void)goal_ptr;
75 (void)dt_s;
76 (void)result_ptr;
77
78 goto_setpoint_ptr_->update(position_target_f_glob_, heading_target_rad_);
79
80 // Remaining distance to target
81 Eigen::Vector3d distance_f_ned =
82 px4_ros2::vectorToGlobalPosition(vehicle_global_position_ptr_->position(), position_target_f_glob_)
83 .cast<double>();
84 tf2::convert(distance_f_ned, feedback_ptr->remaining_distance_f_ned);
85
86 // Estimated remaining time. Use only velocity in direction of target for estimation.
87 feedback_ptr->remaining_time_s =
88 distance_f_ned.norm() /
89 (vehicle_local_position_ptr_->velocityNed().cast<double>().dot(distance_f_ned.normalized()));
90
91 if (IsPositionReached(position_target_f_glob_)) {
92 completed(px4_ros2::Result::Success);
93 }
94 }
95};
96
97class GoToSkill : public ModeExecutorFactory<GoToActionType, GoToMode>
98{
99public:
100 explicit GoToSkill(const rclcpp::NodeOptions & options)
101 : ModeExecutorFactory{_AUTO_APMS_PX4__GOTO_ACTION_NAME, options}
102 {
103 }
104};
105
106} // namespace auto_apms_px4
107
108#include "rclcpp_components/register_node_macro.hpp"
109RCLCPP_COMPONENTS_REGISTER_NODE(auto_apms_px4::GoToSkill)
Helper template class that creates a ModeExecutor for a custom PX4 mode implemented by inheriting fro...
Implementation of PX4 mode peers offered by px4_ros2_cpp enabling integration with AutoAPMS.
Definition mode.hpp:26