15#include "px4_ros2/control/setpoint_types/goto.hpp"
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"
27using GoToActionType = auto_apms_interfaces::action::GoTo;
29class GoToGlobalMode :
public PositionAwareMode<GoToActionType>
31 std::shared_ptr<px4_ros2::GotoGlobalSetpointType> goto_global_setpoint_ptr_;
32 Eigen::Vector3d position_target_f_glob_;
33 float heading_target_rad_;
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}
41 goto_global_setpoint_ptr_ = std::make_shared<px4_ros2::GotoGlobalSetpointType>(*
this);
45 void OnActivateWithGoal(std::shared_ptr<const Goal> goal_ptr)
final
47 position_target_f_glob_ = Eigen::Vector3d(goal_ptr->pos.x, goal_ptr->pos.y, goal_ptr->pos.z);
50 if (goal_ptr->head_towards_destination) {
53 px4_ros2::headingToGlobalPosition(vehicle_global_position_ptr_->position(), position_target_f_glob_);
55 heading_target_rad_ = px4_ros2::wrapPi(px4_ros2::degToRad(goal_ptr->heading_clockwise_from_north_deg));
58 auto double_to_string = [](
double num,
int decimals) {
59 std::stringstream stream;
60 stream << std::fixed << std::setprecision(decimals) << num;
65 node().get_logger(),
"GoToGlobal 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(), px4_ros2::radToDeg(heading_target_rad_));
71 void UpdateSetpointWithGoal(
72 float , std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
73 std::shared_ptr<Result> result_ptr)
final
75 goto_global_setpoint_ptr_->update(
76 position_target_f_glob_, heading_target_rad_, goal_ptr->max_horizontal_vel_m_s, goal_ptr->max_vertical_vel_m_s,
77 px4_ros2::degToRad(goal_ptr->max_heading_rate_deg_s));
80 Eigen::Vector3d distance_f_ned =
81 px4_ros2::vectorToGlobalPosition(vehicle_global_position_ptr_->position(), position_target_f_glob_)
83 tf2::convert(distance_f_ned, feedback_ptr->remaining_dist);
86 feedback_ptr->remaining_heading_deg =
87 px4_ros2::radToDeg(px4_ros2::wrapPi(heading_target_rad_ - vehicle_attitude_ptr_->yaw()));
90 feedback_ptr->remaining_time_s =
91 distance_f_ned.norm() /
92 (vehicle_local_position_ptr_->velocityNed().cast<double>().dot(distance_f_ned.normalized()));
95 IsGlobalPositionReached(
96 position_target_f_glob_, goal_ptr->reached_thresh_pos_m, goal_ptr->reached_thresh_vel_m_s) &&
97 IsHeadingReached(heading_target_rad_, px4_ros2::degToRad(goal_ptr->reached_thresh_heading_deg))) {
98 result_ptr->remaining_dist = feedback_ptr->remaining_dist;
99 result_ptr->remaining_heading_deg = feedback_ptr->remaining_heading_deg;
100 completed(px4_ros2::Result::Success);
105class GoToLocalMode :
public PositionAwareMode<GoToActionType>
107 std::shared_ptr<px4_ros2::GotoSetpointType> goto_local_setpoint_ptr_;
108 Eigen::Vector3d position_target_f_ned_;
109 float heading_target_rad_;
113 rclcpp::Node & node,
const px4_ros2::ModeBase::Settings & settings,
const std::string & topic_namespace_prefix,
114 std::shared_ptr<ActionContextType> action_context_ptr)
115 : PositionAwareMode{node, settings, topic_namespace_prefix, action_context_ptr}
117 goto_local_setpoint_ptr_ = std::make_shared<px4_ros2::GotoSetpointType>(*
this);
121 void OnActivateWithGoal(std::shared_ptr<const Goal> goal_ptr)
final
123 position_target_f_ned_ = Eigen::Vector3d(goal_ptr->pos.x, goal_ptr->pos.y, goal_ptr->pos.z);
126 if (goal_ptr->head_towards_destination) {
128 const px4_msgs::msg::VehicleLocalPosition & pos = vehicle_local_position_ptr_->last();
129 const Eigen::Vector2d pos_vec(pos.x, pos.y);
130 const Eigen::Vector2d d = position_target_f_ned_.head<2>() - pos_vec;
131 heading_target_rad_ = px4_ros2::wrapPi(atan2(d.y(), d.x()));
133 heading_target_rad_ = px4_ros2::wrapPi(px4_ros2::degToRad(goal_ptr->heading_clockwise_from_north_deg));
136 auto double_to_string = [](
double num,
int decimals) {
137 std::stringstream stream;
138 stream << std::fixed << std::setprecision(decimals) << num;
143 node().get_logger(),
"GoToLocal target: Position: [%sm, %sm, %sm] - Heading: %f°",
144 double_to_string(position_target_f_ned_.x(), 2).c_str(), double_to_string(position_target_f_ned_.y(), 2).c_str(),
145 double_to_string(position_target_f_ned_.z(), 2).c_str(), px4_ros2::radToDeg(heading_target_rad_));
148 void UpdateSetpointWithGoal(
149 float , std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
150 std::shared_ptr<Result> result_ptr)
final
152 goto_local_setpoint_ptr_->update(
153 position_target_f_ned_.cast<
float>(), heading_target_rad_, goal_ptr->max_horizontal_vel_m_s, goal_ptr->max_vertical_vel_m_s,
154 px4_ros2::degToRad(goal_ptr->max_heading_rate_deg_s));
157 Eigen::Vector3d distance_f_ned =
158 px4_ros2::vectorToGlobalPosition(vehicle_global_position_ptr_->position(), position_target_f_ned_).cast<
double>();
159 tf2::convert(distance_f_ned, feedback_ptr->remaining_dist);
162 feedback_ptr->remaining_heading_deg =
163 px4_ros2::radToDeg(px4_ros2::wrapPi(heading_target_rad_ - vehicle_attitude_ptr_->yaw()));
166 feedback_ptr->remaining_time_s =
167 distance_f_ned.norm() /
168 (vehicle_local_position_ptr_->velocityNed().cast<double>().dot(distance_f_ned.normalized()));
171 IsLocalPositionReached(
172 position_target_f_ned_, goal_ptr->reached_thresh_pos_m, goal_ptr->reached_thresh_vel_m_s) &&
173 IsHeadingReached(heading_target_rad_, px4_ros2::degToRad(goal_ptr->reached_thresh_heading_deg))) {
174 result_ptr->remaining_dist = feedback_ptr->remaining_dist;
175 result_ptr->remaining_heading_deg = feedback_ptr->remaining_heading_deg;
176 completed(px4_ros2::Result::Success);
184 explicit GoToGlobalSkill(
const rclcpp::NodeOptions & options)
185 : ModeExecutorFactory{_AUTO_APMS_PX4__GOTO_GLOBAL_ACTION_NAME, options}
193 explicit GoToLocalSkill(
const rclcpp::NodeOptions & options)
194 : ModeExecutorFactory{_AUTO_APMS_PX4__GOTO_LOCAL_ACTION_NAME, options}
201#include "rclcpp_components/register_node_macro.hpp"
202RCLCPP_COMPONENTS_REGISTER_NODE(auto_apms_px4::GoToGlobalSkill)
203RCLCPP_COMPONENTS_REGISTER_NODE(auto_apms_px4::GoToLocalSkill)
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.