EasyNav Plugins
Loading...
Searching...
No Matches
SerestController.hpp
Go to the documentation of this file.
1// Copyright 2025 Intelligent Robotics Lab
2//
3// This file is part of the project Easy Navigation (EasyNav in short)
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#ifndef EASYNAV_SEREST_CONTROLLER__SERESTCONTROLLER_HPP_
17#define EASYNAV_SEREST_CONTROLLER__SERESTCONTROLLER_HPP_
18
19#include <vector>
20#include <string>
21
22#include "rclcpp/time.hpp"
23#include "nav_msgs/msg/odometry.hpp"
24#include "nav_msgs/msg/path.hpp"
25#include "geometry_msgs/msg/twist_stamped.hpp"
26
27#include "easynav_core/ControllerMethodBase.hpp"
28#include "easynav_common/types/NavState.hpp"
29
30namespace easynav
31{
32
33
51class SerestController : public ControllerMethodBase
52{
53public:
58
63 void on_initialize() override;
64
78 void update_rt(NavState & nav_state) override;
79
86 struct Vec2
87 {
88 double x;
89 double y;
90
92 inline Vec2 operator+(const Vec2 & b) const {return {x + b.x, y + b.y};}
94 inline Vec2 operator-(const Vec2 & b) const {return {x - b.x, y - b.y};}
96 inline Vec2 operator*(double s) const {return {x * s, y * s};}
97
99 friend inline Vec2 operator*(double s, const Vec2 & a) {return {a.x * s, a.y * s};}
100 };
101
102private:
106 struct PathData
107 {
108 std::vector<Vec2> pts;
109 std::vector<double> s_acc;
110 };
111
115 struct Projection
116 {
117 size_t seg_idx{0};
118 double s_star{0.0};
119 Vec2 closest{0.0, 0.0};
120 double t{0.0};
121 };
122
126 struct RefKinematics
127 {
128 double psi_ref{0.0};
129 double kappa_hat{0.0};
130 };
131
137 PathData build_path_data(const nav_msgs::msg::Path & path) const;
138
145 Projection project_on_path(const PathData & pd, const Vec2 & p) const;
146
154 RefKinematics ref_heading_and_curvature(
155 const PathData & pd, const Projection & prj, double v_prev) const;
156
166 void frenet_errors(
167 const Vec2 & robot_xy, double robot_yaw,
168 const Projection & prj, double psi_ref,
169 double & e_y, double & e_theta) const;
170
180 double closest_obstacle_distance(
181 const NavState & nav_state);
182
189 double v_safe_from_distance(double d, double slope_sin = 0.0) const;
190
196 double v_curvature_limit(double kappa_hat) const;
197
198 // Gestiona dt y actualiza last_update_ts_. Devuelve dt robusto.
199 double compute_dt_and_update_clock();
200
201 // Comprueba entradas mínimas. Publica stop si faltan y devuelve false.
202 // Si todo ok, rellena 'path' y 'odom' y devuelve true.
203 bool fetch_required_inputs(
204 NavState & nav_state,
205 nav_msgs::msg::Path & path,
206 nav_msgs::msg::Odometry & odom);
207
208 // Extrae estado del robot (xy, yaw) desde la odometría.
209 void robot_state_from_odom(
210 const nav_msgs::msg::Odometry & odom,
211 Vec2 & robot_xy, double & yaw) const;
212
213 // Calcula información de goal y zonas slow/stop.
214 void compute_goal_zone(
215 const nav_msgs::msg::Path & path,
216 const Vec2 & robot_xy, double robot_yaw,
217 double & dist_xy_goal, double & e_theta_goal,
218 double & stop_r, double & slow_r, double & gamma_slow,
219 Vec2 & goal_xy, double & yaw_goal) const;
220
221 // Calcula límites de seguridad globales (distancia obstáculo, v_safe, v_curv).
222 void safety_limits(
223 const NavState & nav_state,
224 const RefKinematics & rk,
225 double & d_closest, double & v_safe, double & v_curv);
226
227 // Aplica corner‑guard: ajusta v_prog_ref y obtiene omega_boost + término ápice.
228 void apply_corner_guard(
229 const RefKinematics & rk, double e_y, double e_theta,
230 double & v_prog_ref, double & omega_boost, double & ey_apex_term) const;
231
232 // Determina si debe hacerse giro en el sitio en esta iteración.
233 bool should_turn_in_place(
234 bool allow_reverse, double e_theta, double e_theta_goal,
235 double dist_to_end, double turn_in_place_thr) const;
236
237 // Fase de alineación final: publica y devuelve true si se ha gestionado aquí.
238 bool maybe_final_align_and_publish(
239 NavState & nav_state, const nav_msgs::msg::Path & path,
240 double dist_xy_goal, double stop_r, double e_theta_goal,
241 double gamma_slow, double dt);
242
243 // Aplica rate‑limit y saturaciones finales sobre (vlin, vrot) y actualiza last_*.
244 void rate_limit_and_saturate(double dt, double & vlin, double & vrot);
245
246 // Publica cmd_vel y variables de depuración comunes del final de update_rt.
247 void publish_cmd_and_debug(
248 NavState & nav_state, const nav_msgs::msg::Path & path,
249 double vlin, double vrot,
250 double e_y, double e_theta, double kappa_hat,
251 double d_closest, double v_safe, double v_curv, double alpha,
252 bool allow_reverse, double dist_to_end,
253 double dist_xy_goal, double gamma_slow,
254 int in_final_align, int arrived);
255
256 // Publica parada inmediata con frame y stamp actuales.
257 void publish_stop(NavState & nav_state, const std::string & frame_id);
258
259 // --- Parameters ---
260
262 bool allow_reverse_{false};
264 double v_progress_min_{0.05};
266 double k_s_share_max_{0.5};
267
269 double max_linear_speed_{0.6};
271 double max_angular_speed_{1.5};
273 double max_linear_acc_{0.8};
275 double max_angular_acc_{2.0};
276
278 double k_s_{0.8}, k_theta_{2.0}, k_y_{1.2}, ell_{0.3};
280 double v_ref_{0.6};
282 double eps_{1e-3};
283
285 double a_acc_{0.8};
287 double a_brake_{1.2};
289 double a_lat_max_{1.5};
291 double d0_margin_{0.30};
293 double tau_latency_{0.10};
295 double d_hard_{0.20};
297 double t_emerg_{0.25};
298
300 double blend_base_{0.6};
302 double blend_k_per_v_{0.6};
304 double kappa_max_{2.5};
305
307 double dist_search_radius_{2.0};
308
310 double goal_pos_tol_{0.05};
312 double goal_yaw_tol_deg_{5.0};
314 double slow_radius_{0.60};
316 double slow_min_speed_{0.03};
317
319 double final_align_k_{2.0};
321 double final_align_wmax_{0.6};
322
324 bool corner_guard_enable_{true};
326 double corner_gain_ey_{1.5};
328 double corner_gain_eth_{0.7};
330 double corner_gain_kappa_{0.4};
332 double corner_min_alpha_{0.35};
334 double corner_boost_omega_{0.8};
336 double apex_ey_des_{0.05};
338 double a_lat_soft_{1.1};
339
340 // --- Internal state ---
341
342 bool startup_anchor_active_{true};
343 geometry_msgs::msg::Pose goal_pose_last_{};
344 // Activa/desactiva giro en el sitio con histéresis
345 bool tip_active_{false};
346
348 double last_vlin_{0.0};
350 double last_vrot_{0.0};
352 rclcpp::Time last_update_ts_;
354 rclcpp::Time last_input_ts_;
356 geometry_msgs::msg::TwistStamped twist_stamped_;
357};
358
365inline SerestController::Vec2 v2(double x, double y) {return {x, y};}
366
373inline double dot(const SerestController::Vec2 & a, const SerestController::Vec2 & b)
374{
375 return a.x * b.x + a.y * b.y;
376}
377
384inline double crossz(const SerestController::Vec2 & a, const SerestController::Vec2 & b)
385{
386 return a.x * b.y - a.y * b.x;
387}
388
394inline double norm(const SerestController::Vec2 & a) {return std::hypot(a.x, a.y);}
395
402{
403 double n = norm(a);
404 return n > 1e-9 ? SerestController::Vec2{a.x / n, a.y / n} : SerestController::Vec2{1.0, 0.0};
405}
406
407} // namespace easynav
408
409#endif // EASYNAV_SEREST_CONTROLLER__SERESTCONTROLLER_HPP_
void update_rt(NavState &nav_state) override
Real-time control update (called ~20–30 Hz).
Definition SerestController.cpp:626
SerestController()
Default constructor.
~SerestController() override
Destructor.
void on_initialize() override
Initialize parameters and internal state.
Definition SerestController.cpp:40
Provides a mapping for often used cost values.
Definition cost_values.hpp:41
SerestController::Vec2 v2(double x, double y)
Construct a 2D vector.
Definition SerestController.hpp:365
double crossz(const SerestController::Vec2 &a, const SerestController::Vec2 &b)
2D cross product Z component (a.x*b.y - a.y*b.x).
Definition SerestController.hpp:384
double dot(const SerestController::Vec2 &a, const SerestController::Vec2 &b)
Dot product between two 2D vectors.
Definition SerestController.hpp:373
SerestController::Vec2 normalize(const SerestController::Vec2 &a)
Normalize a 2D vector, with a safe fallback for very small norms.
Definition SerestController.hpp:401
double norm(const SerestController::Vec2 &a)
Euclidean norm (length) of a 2D vector.
Definition SerestController.hpp:394
Simple 2D vector utility type.
Definition SerestController.hpp:87
Vec2 operator+(const Vec2 &b) const
Vector addition.
Definition SerestController.hpp:92
Vec2 operator*(double s) const
Scalar multiplication (vector * scalar).
Definition SerestController.hpp:96
Vec2 operator-(const Vec2 &b) const
Vector subtraction.
Definition SerestController.hpp:94
friend Vec2 operator*(double s, const Vec2 &a)
Scalar multiplication (scalar * vector).
Definition SerestController.hpp:99
double y
Y component.
Definition SerestController.hpp:89
double x
X component.
Definition SerestController.hpp:88