controls  3.0.0
ControlsROS2Wrapper.h
Go to the documentation of this file.
1 #ifndef CONTROLS_NODES_CONTROLSROS2WRAPPER_H
2 #define CONTROLS_NODES_CONTROLSROS2WRAPPER_H
3 
5 #include <utils/Types.h>
6 #include <utils/concurrentqueue.h>
7 #include <vehicle/Vehicle.h>
8 #include <yaml-cpp/yaml.h>
9 
10 #include <atomic>
11 #include <bb_controls_msgs/action/locomotion.hpp>
12 #include <bb_controls_msgs/msg/controller_status.hpp>
13 #include <bb_controls_msgs/msg/thrusters.hpp>
14 #include <bb_controls_msgs/srv/controller.hpp>
15 #include <bb_controls_msgs/srv/encircle_traj.hpp>
16 #include <bb_controls_msgs/srv/spline_traj.hpp>
17 #include <bb_planner_msgs/srv/get_plan_through_poses.hpp>
18 #include <bb_sensor_msgs/msg/batteries_with_id.hpp>
19 #include <boost/uuid/uuid.hpp>
20 #include <boost/uuid/uuid_generators.hpp>
21 #include <boost/uuid/uuid_io.hpp>
22 #include <controls/controls_parameters.hpp>
23 #include <memory>
24 #include <mutex>
25 #include <rclcpp_action/rclcpp_action.hpp>
26 #include <rclcpp_action/server.hpp>
27 #include <std_msgs/msg/bool.hpp>
28 #include <string>
29 #include <thread>
30 
60 class ControlsROS2Wrapper : public rclcpp::Node {
61 public:
70  explicit ControlsROS2Wrapper(const std::string& name, std::unique_ptr<Vehicle> robot,
71  std::string body_frame_tf_name = "base_link", std::string world_frame_tf_name = "map");
72 
73  ~ControlsROS2Wrapper() override;
74 
75  // Non-copyable and non-movable: mutex, atomic, unique_ptr, and thread members
80 
81  using Locomotion = bb_controls_msgs::action::Locomotion;
82  using GoalHandleLocomotion = rclcpp_action::ServerGoalHandle<Locomotion>;
83 
84 protected:
86  static constexpr int CONTROL_LOOP_RATE = 20;
87 
89  static constexpr double MIN_DEPTH_CLAMP = 0.00;
90 
92  static constexpr double MAX_VEL = 1.0;
93 
95  static constexpr double TWIST_LPF_RESET_DT = 0.5;
96 
98  std::once_flag control_loop_started_;
99 
101  const std::string vehicle_frame_id_;
102 
104  const std::string world_frame_id_;
105 
107  std::unique_ptr<Vehicle> auv_;
108 
109  // ROS subscribers
110  rclcpp::Subscription<nav_msgs::msg::Odometry>::SharedPtr world_sub_;
111  rclcpp::Subscription<bb_sensor_msgs::msg::BatteriesWithId>::SharedPtr battery_sub_;
112  rclcpp::Subscription<geometry_msgs::msg::Twist>::SharedPtr teleop_force_sub_;
113 
114  // ROS publishers
115  rclcpp::Publisher<geometry_msgs::msg::WrenchStamped>::SharedPtr pub_controller_force_;
116  rclcpp::Publisher<bb_controls_msgs::msg::ControllerStatus>::SharedPtr pub_status_;
117  rclcpp::Publisher<geometry_msgs::msg::PoseArray>::SharedPtr pub_traj_viz_;
118  rclcpp::Publisher<bb_controls_msgs::msg::Thrusters>::SharedPtr pub_thruster_commands_;
119  rclcpp::Publisher<geometry_msgs::msg::WrenchStamped>::SharedPtr pub_allocator_force_;
120  rclcpp::Publisher<bb_controls_msgs::msg::ThrusterForces>::SharedPtr pub_thruster_forces_;
121 
122  rclcpp::TimerBase::SharedPtr control_loop_timer_;
123  rclcpp::TimerBase::SharedPtr debug_publish_timer_;
124 
126  moodycamel::ConcurrentQueue<DebugMessage> debug_queue_;
127 
128  rclcpp::Service<bb_controls_msgs::srv::Controller>::SharedPtr controller_srv_;
129  rclcpp::Service<bb_controls_msgs::srv::SplineTraj>::SharedPtr spline_traj_srv_;
130  rclcpp::Service<bb_controls_msgs::srv::EncircleTraj>::SharedPtr encircle_traj_srv_;
131 
132  rclcpp_action::Server<Locomotion>::SharedPtr poly_action_server_;
133  std::mutex action_goal_mutex_;
134  std::shared_ptr<GoalHandleLocomotion> current_action_goal_;
135 
137  std::atomic<bool> shutdown_requested_{false};
138 
141 
143  std::shared_ptr<controls::ParamListener> param_listener_;
144 
146  controls::Params config_;
147 
149  double prev_time_ = 0.0;
150 
152  Array6d twist_lpf_tau_ = Array6d::Zero();
153 
155  Vector6d twist_lpf_state_ = Vector6d::Zero();
156 
158  bool twist_lpf_init_ = false;
159 
162 
169  void control_loop();
170 
177 
184  void debug_publish_loop();
185 
188 
193 
199  void sub_callback_world_position(const nav_msgs::msg::Odometry::ConstSharedPtr& m);
200 
206  void sub_callback_battery_voltage(const bb_sensor_msgs::msg::BatteriesWithId::ConstSharedPtr& msg);
207 
215  void sub_callback_teleop_force(const geometry_msgs::msg::Twist::ConstSharedPtr& msg);
216 
223  void srv_callback_controller(const std::shared_ptr<bb_controls_msgs::srv::Controller::Request> req,
224  std::shared_ptr<bb_controls_msgs::srv::Controller::Response> res);
225 
232  void srv_callback_trajectory_xyz(const std::shared_ptr<bb_controls_msgs::srv::SplineTraj::Request> req,
233  std::shared_ptr<bb_controls_msgs::srv::SplineTraj::Response> res);
234 
241  void srv_callback_encircle_traj(const std::shared_ptr<bb_controls_msgs::srv::EncircleTraj::Request> req,
242  std::shared_ptr<bb_controls_msgs::srv::EncircleTraj::Response> res);
243 
252  rclcpp_action::GoalResponse poly_handle_goal(const rclcpp_action::GoalUUID& uuid,
253  std::shared_ptr<const Locomotion::Goal> goal);
254 
262  rclcpp_action::CancelResponse poly_handle_cancel(const std::shared_ptr<GoalHandleLocomotion> goal_handle);
263 
269  void poly_handle_accepted(const std::shared_ptr<GoalHandleLocomotion> goal_handle);
270 
280  void poly_execute_action(const std::shared_ptr<GoalHandleLocomotion> goal_handle);
281 };
282 
283 #endif // CONTROLS_NODES_CONTROLSROS2WRAPPER_H
Eigen::Array< double, 6, 1 > Array6d
Definition: Types.h:40
Eigen::Matrix< double, 6, 1 > Vector6d
Definition: Types.h:29
ROS2 node that wraps the Vehicle control stack and exposes its interface to the rest of the system.
Definition: ControlsROS2Wrapper.h:60
void debug_publish_loop()
Drains the debug queue and publishes all pending messages.
Definition: ControlsROS2Wrapper.cpp:174
rclcpp::Subscription< geometry_msgs::msg::Twist >::SharedPtr teleop_force_sub_
Definition: ControlsROS2Wrapper.h:112
rclcpp::Publisher< bb_controls_msgs::msg::ThrusterForces >::SharedPtr pub_thruster_forces_
Definition: ControlsROS2Wrapper.h:120
Array6d twist_lpf_tau_
Per-axis twist low-pass time constants (s); 0 disables an axis.
Definition: ControlsROS2Wrapper.h:152
~ControlsROS2Wrapper() override
Definition: ControlsROS2Wrapper.cpp:110
void sub_callback_teleop_force(const geometry_msgs::msg::Twist::ConstSharedPtr &msg)
Teleop subscriber callback — allocates the raw force directly if the controller is disabled.
Definition: ControlsROS2Wrapper.cpp:248
rclcpp::TimerBase::SharedPtr debug_publish_timer_
Definition: ControlsROS2Wrapper.h:123
std::shared_ptr< controls::ParamListener > param_listener_
Declares all parameters, validates updates, and exposes the generated Params struct.
Definition: ControlsROS2Wrapper.h:143
const std::string world_frame_id_
TF frame_id of the world frame.
Definition: ControlsROS2Wrapper.h:104
rclcpp_action::GoalResponse poly_handle_goal(const rclcpp_action::GoalUUID &uuid, std::shared_ptr< const Locomotion::Goal > goal)
Action server goal handler — rejects goals when the controller is disabled.
Definition: ControlsROS2Wrapper.cpp:335
rclcpp_action::CancelResponse poly_handle_cancel(const std::shared_ptr< GoalHandleLocomotion > goal_handle)
Action server cancel handler — always accepts cancel requests.
Definition: ControlsROS2Wrapper.cpp:345
std::shared_ptr< GoalHandleLocomotion > current_action_goal_
Definition: ControlsROS2Wrapper.h:134
rclcpp::Subscription< nav_msgs::msg::Odometry >::SharedPtr world_sub_
Definition: ControlsROS2Wrapper.h:110
std::mutex action_goal_mutex_
Definition: ControlsROS2Wrapper.h:133
void apply_config_to_vehicle()
Applies config_ to the Vehicle's dynamics model, controller gains, and limits.
Definition: ControlsROS2Wrapper.cpp:556
static constexpr double MIN_DEPTH_CLAMP
Minimum depth value clamp to avoid near-zero depth noise (m)
Definition: ControlsROS2Wrapper.h:89
Vector6d twist_lpf_state_
State of the per-axis first-order low-pass filter on the measured twist.
Definition: ControlsROS2Wrapper.h:155
void sub_callback_battery_voltage(const bb_sensor_msgs::msg::BatteriesWithId::ConstSharedPtr &msg)
Battery subscriber callback — forwards the minimum cell voltage to the Vehicle.
Definition: ControlsROS2Wrapper.cpp:240
static constexpr int CONTROL_LOOP_RATE
Control loop frequency in Hz.
Definition: ControlsROS2Wrapper.h:86
rclcpp::Service< bb_controls_msgs::srv::SplineTraj >::SharedPtr spline_traj_srv_
Definition: ControlsROS2Wrapper.h:129
rclcpp::Service< bb_controls_msgs::srv::EncircleTraj >::SharedPtr encircle_traj_srv_
Definition: ControlsROS2Wrapper.h:130
rclcpp_action::ServerGoalHandle< Locomotion > GoalHandleLocomotion
Definition: ControlsROS2Wrapper.h:82
rclcpp::Publisher< geometry_msgs::msg::WrenchStamped >::SharedPtr pub_controller_force_
Definition: ControlsROS2Wrapper.h:115
bool twist_lpf_init_
Whether twist_lpf_state_ holds a valid sample.
Definition: ControlsROS2Wrapper.h:158
std::once_flag control_loop_started_
Flag for starting control loop.
Definition: ControlsROS2Wrapper.h:98
static constexpr double MAX_VEL
Max plausible vehicle speed for odometry jump rejection (m/s)
Definition: ControlsROS2Wrapper.h:92
void poly_execute_action(const std::shared_ptr< GoalHandleLocomotion > goal_handle)
Executes a Locomotion action: plans trajectory, waits for completion, checks tolerances.
Definition: ControlsROS2Wrapper.cpp:370
ControlsROS2Wrapper & operator=(ControlsROS2Wrapper &&)=delete
rclcpp::Publisher< geometry_msgs::msg::WrenchStamped >::SharedPtr pub_allocator_force_
Definition: ControlsROS2Wrapper.h:119
rclcpp::CallbackGroup::SharedPtr actions_cb_group_
Definition: ControlsROS2Wrapper.h:160
std::thread action_execute_thread_
Thread running action execute method; joined before destruction.
Definition: ControlsROS2Wrapper.h:140
void control_loop()
Executes one iteration of the 20 Hz control loop.
Definition: ControlsROS2Wrapper.cpp:122
std::atomic< bool > shutdown_requested_
Signals the action execution thread to exit its loop.
Definition: ControlsROS2Wrapper.h:137
moodycamel::ConcurrentQueue< DebugMessage > debug_queue_
Lock-free queue through which the control loop passes debug messages to the publish timer.
Definition: ControlsROS2Wrapper.h:126
rclcpp::CallbackGroup::SharedPtr odom_cb_group_
Definition: ControlsROS2Wrapper.h:160
rclcpp::TimerBase::SharedPtr control_loop_timer_
Definition: ControlsROS2Wrapper.h:122
ControlsROS2Wrapper & operator=(const ControlsROS2Wrapper &)=delete
rclcpp::CallbackGroup::SharedPtr aux_cb_group_
Definition: ControlsROS2Wrapper.h:161
ControlsROS2Wrapper(ControlsROS2Wrapper &&)=delete
ControlsROS2Wrapper(const ControlsROS2Wrapper &)=delete
void refresh_params_if_changed()
Pulls the latest validated params from the ParamListener and applies them on change.
Definition: ControlsROS2Wrapper.cpp:538
void srv_callback_trajectory_xyz(const std::shared_ptr< bb_controls_msgs::srv::SplineTraj::Request > req, std::shared_ptr< bb_controls_msgs::srv::SplineTraj::Response > res)
Service callback to request a straight XYZ or multi-waypoint spline trajectory.
Definition: ControlsROS2Wrapper.cpp:278
static constexpr double TWIST_LPF_RESET_DT
Odometry gap (s) beyond which the twist low-pass filter re-initialises.
Definition: ControlsROS2Wrapper.h:95
rclcpp::Publisher< bb_controls_msgs::msg::ControllerStatus >::SharedPtr pub_status_
Definition: ControlsROS2Wrapper.h:116
const std::string vehicle_frame_id_
TF child_frame_id of the vehicle body frame.
Definition: ControlsROS2Wrapper.h:101
void poly_handle_accepted(const std::shared_ptr< GoalHandleLocomotion > goal_handle)
Action server accepted handler — preempts any active goal and starts a new execute thread.
Definition: ControlsROS2Wrapper.cpp:350
rclcpp::Subscription< bb_sensor_msgs::msg::BatteriesWithId >::SharedPtr battery_sub_
Definition: ControlsROS2Wrapper.h:111
void srv_callback_encircle_traj(const std::shared_ptr< bb_controls_msgs::srv::EncircleTraj::Request > req, std::shared_ptr< bb_controls_msgs::srv::EncircleTraj::Response > res)
Service callback to request a circular arc (encircle) trajectory.
Definition: ControlsROS2Wrapper.cpp:305
void srv_callback_controller(const std::shared_ptr< bb_controls_msgs::srv::Controller::Request > req, std::shared_ptr< bb_controls_msgs::srv::Controller::Response > res)
Service callback to enable (stationkeep) or disable the controller.
Definition: ControlsROS2Wrapper.cpp:266
rclcpp::Publisher< bb_controls_msgs::msg::Thrusters >::SharedPtr pub_thruster_commands_
Definition: ControlsROS2Wrapper.h:118
controls::Params config_
Local snapshot of ROS parameters, pushed to Vehicle subsystems on change.
Definition: ControlsROS2Wrapper.h:146
rclcpp_action::Server< Locomotion >::SharedPtr poly_action_server_
Definition: ControlsROS2Wrapper.h:132
rclcpp::Service< bb_controls_msgs::srv::Controller >::SharedPtr controller_srv_
Definition: ControlsROS2Wrapper.h:128
void sub_callback_world_position(const nav_msgs::msg::Odometry::ConstSharedPtr &m)
Odometry subscriber callback — updates vehicle state and starts the control loop.
Definition: ControlsROS2Wrapper.cpp:201
rclcpp::CallbackGroup::SharedPtr control_loop_cb_group_
Definition: ControlsROS2Wrapper.h:160
void publish_controller_status(const Vehicle::ControllerStatus &status)
Publishes a ControllerStatus message from the given status snapshot.
Definition: ControlsROS2Wrapper.cpp:160
bb_controls_msgs::action::Locomotion Locomotion
Definition: ControlsROS2Wrapper.h:81
rclcpp::Publisher< geometry_msgs::msg::PoseArray >::SharedPtr pub_traj_viz_
Definition: ControlsROS2Wrapper.h:117
ControlsROS2Wrapper(const std::string &name, std::unique_ptr< Vehicle > robot, std::string body_frame_tf_name="base_link", std::string world_frame_tf_name="map")
Constructs the node, initialises all ROS interfaces, and loads parameters.
Definition: ControlsROS2Wrapper.cpp:22
double prev_time_
ROS timestamp of the previous control loop iteration.
Definition: ControlsROS2Wrapper.h:149
rclcpp::CallbackGroup::SharedPtr services_cb_group_
Definition: ControlsROS2Wrapper.h:160
std::unique_ptr< Vehicle > auv_
Encapsulated vehicle control stack.
Definition: ControlsROS2Wrapper.h:107
Snapshot of controller status exposed to external callers.
Definition: Vehicle.h:51