38template <
class ActionT>
39class ModeBase :
public px4_ros2::ModeBase
43 using Goal =
typename ActionContextType::Goal;
44 using Result =
typename ActionContextType::Result;
45 using Feedback =
typename ActionContextType::Feedback;
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}
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 {}
61 void onActivate()
override;
62 void updateSetpoint(
float dt_s)
override;
64 const std::shared_ptr<ActionContextType> action_context_ptr_;
67template <
class ActionT>
68void ModeBase<ActionT>::OnActivateWithGoal(std::shared_ptr<const Goal> goal_ptr)
73template <
class ActionT>
74void ModeBase<ActionT>::onActivate()
76 OnActivateWithGoal(action_context_ptr_->getGoalHandlePtr()->get_goal());
79template <
class ActionT>
80void ModeBase<ActionT>::updateSetpoint(
float dt_s)
82 UpdateSetpointWithGoal(
83 dt_s, action_context_ptr_->getGoalHandlePtr()->get_goal(), action_context_ptr_->getFeedbackPtr(),
84 action_context_ptr_->getResultPtr());
87template <
class ActionT>
88class PositionAwareMode :
public ModeBase<ActionT>
91 using typename ModeBase<ActionT>::ActionContextType;
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}
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);
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;
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_;
113template <
class ActionT>
114bool PositionAwareMode<ActionT>::IsPositionReached(
const Eigen::Vector3d & target_position_f_glob)
const
116 static constexpr float kPositionErrorThresholdMeter = 0.5f;
117 static constexpr float kVelocityErrorThresholdMeterPerSecond = 0.3f;
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);
124template <
class ActionT>
125bool PositionAwareMode<ActionT>::IsAltitudeReached(
float target_altitude_amsl_m)
const
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);
132template <
class ActionT>
133bool PositionAwareMode<ActionT>::IsHeadingReached(
float target_heading_rad)
const
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;
Helper class that stores contextual information related to a ROS 2 action.