17#include "auto_apms_px4/mode.hpp"
18#include "auto_apms_px4/mode_executor.hpp"
19#include "auto_apms_px4_interfaces/action/set_actuators.hpp"
20#include "px4_ros2/control/setpoint_types/direct_actuators.hpp"
25using SetActuatorsActionType = auto_apms_px4_interfaces::action::SetActuators;
27class SetActuatorsMode :
public ModeBase<SetActuatorsActionType>
29 std::shared_ptr<px4_ros2::DirectActuatorsSetpointType> actuator_setpoint_ptr_;
30 rclcpp::Time activation_time_;
31 bool commands_sent_{
false};
35 rclcpp::Node & node, px4_ros2::ModeBase::Settings settings, std::shared_ptr<ActionContextType> action_context_ptr)
36 : ModeBase{node, settings, action_context_ptr}
38 actuator_setpoint_ptr_ = std::make_shared<px4_ros2::DirectActuatorsSetpointType>(*
this);
42 void OnActivateWithGoal(std::shared_ptr<const Goal> )
final
44 activation_time_ = node().get_clock()->now();
45 commands_sent_ =
false;
48 void UpdateSetpointWithGoal(
49 float , std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> ,
50 std::shared_ptr<Result> )
final
52 constexpr auto kNaN = std::numeric_limits<float>::quiet_NaN();
53 constexpr int kMaxMotors = px4_ros2::DirectActuatorsSetpointType::kMaxNumMotors;
54 constexpr int kMaxServos = px4_ros2::DirectActuatorsSetpointType::kMaxNumServos;
57 Eigen::Matrix<float, kMaxMotors, 1> motor_cmds = Eigen::Matrix<float, kMaxMotors, 1>::Constant(kNaN);
58 for (
size_t i = 0; i < std::min(goal_ptr->motor_commands.size(),
static_cast<size_t>(kMaxMotors)); ++i) {
59 motor_cmds(i) = goal_ptr->motor_commands[i];
63 Eigen::Matrix<float, kMaxServos, 1> servo_cmds = Eigen::Matrix<float, kMaxServos, 1>::Constant(kNaN);
64 for (
size_t i = 0; i < std::min(goal_ptr->servo_commands.size(),
static_cast<size_t>(kMaxServos)); ++i) {
65 servo_cmds(i) = goal_ptr->servo_commands[i];
68 const rclcpp::Duration elapsed = node().get_clock()->now() - activation_time_;
69 const rclcpp::Duration hold_duration =
70 rclcpp::Duration::from_nanoseconds(
static_cast<int64_t
>(goal_ptr->hold_period_ms) * 1'000'000LL);
72 if (!commands_sent_ || elapsed < hold_duration) {
74 actuator_setpoint_ptr_->updateMotors(motor_cmds);
75 actuator_setpoint_ptr_->updateServos(servo_cmds);
76 commands_sent_ =
true;
79 actuator_setpoint_ptr_->updateMotors(Eigen::Matrix<float, kMaxMotors, 1>::Constant(kNaN));
80 actuator_setpoint_ptr_->updateServos(Eigen::Matrix<float, kMaxServos, 1>::Constant(kNaN));
81 completed(px4_ros2::Result::Success);
86class SetActuatorsSkill :
public ModeExecutorFactory<SetActuatorsActionType, SetActuatorsMode>
89 explicit SetActuatorsSkill(
const rclcpp::NodeOptions & options)
90 : ModeExecutorFactory{_AUTO_APMS_PX4__SET_ACTUATORS_ACTION_NAME, options}
97#include "rclcpp_components/register_node_macro.hpp"
98RCLCPP_COMPONENTS_REGISTER_NODE(auto_apms_px4::SetActuatorsSkill)
Generic template class for a custom PX4 mode.
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.