libstp
Robotics library for Botball
Loading...
Searching...
No Matches
arc_motion.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <vector>
5
6#include "motion/motion.hpp"
10
12{
32 {
33 double radius_m{0.0}; // Turning radius (always positive)
34 double arc_angle_rad{0.0}; // Total heading change (positive = CCW/left, negative = CW/right)
35 double speed_scale{1.0}; // fraction of max speed; sign = travel direction (<0 = reverse)
36 bool lateral{false}; // true = strafe arc (vy), false = drive arc (vx)
37 };
38
41 {
42 double time_s{0.0};
43 double dt{0.0};
44 // Heading tracking
45 double target_angle_rad{0.0};
46 double heading_rad{0.0};
47 double heading_error_rad{0.0};
48 // Arc progress
49 double arc_position_m{0.0}; // distance traveled along arc
50 double arc_target_m{0.0}; // total arc length
51 // Velocity
53 // Commands
54 double cmd_vx_mps{0.0};
55 double cmd_vy_mps{0.0};
56 double cmd_wz_radps{0.0};
57 // PID internals
58 double pid_raw{0.0};
61 bool saturated{false};
62 };
63
74 class ArcMotion final : public Motion
75 {
76 public:
78
79 void start() override;
80 void update(double dt) override;
81 [[nodiscard]] bool isFinished() const override;
82
89 void startWarm(double heading_offset_rad, double initial_angular_velocity);
90
92 void setSuppressHardStopOnComplete(bool suppress) { suppress_hard_stop_ = suppress; }
93
95 [[nodiscard]] bool hasReachedAngle() const;
96
98 [[nodiscard]] double getFilteredVelocity() const { return filtered_velocity_; }
99
100 [[nodiscard]] const std::vector<ArcMotionTelemetry>& getTelemetry() const { return telemetry_; }
101
102 private:
103 void complete();
104
105 ArcMotionConfig cfg_{};
106 // Travel direction from the sign of speed_scale: +1 forwards, -1 reverse.
107 double travel_dir_{1.0};
108 // Heading target actually tracked by the PID. Equals cfg_.arc_angle_rad
109 // forwards; negated for a reverse arc so the robot turns the opposite way
110 // while the arc centre stays on the same side.
111 double goal_angle_rad_{0.0};
112 double max_angular_velocity_{0.0};
113 ProfiledPIDController profiled_pid_;
114 bool finished_{false};
115 bool suppress_hard_stop_{false};
116 double heading_offset_rad_{0.0};
117
118 // Absolute heading at start; subtracted from current absolute heading to
119 // produce the body-frame arc progress. Replaces the historical
120 // odometry-reset semantics.
121 double initial_absolute_heading_rad_{0.0};
122
123 // Velocity tracking for settling detection
124 double prev_heading_{0.0};
125 double filtered_velocity_{0.0};
126 static constexpr double kVelocityFilterAlpha{0.3};
127 static constexpr double kSettlingVelocity{0.05}; // rad/s
128
129 // Telemetry
130 double elapsed_time_{0.0};
131 std::vector<ArcMotionTelemetry> telemetry_;
132 int cycle_{0};
133 };
134}
void setSuppressHardStopOnComplete(bool suppress)
void update(double dt) override
bool hasReachedAngle() const
void startWarm(double heading_offset_rad, double initial_angular_velocity)
double getFilteredVelocity() const
const std::vector< ArcMotionTelemetry > & getTelemetry() const
ArcMotion(MotionContext ctx, ArcMotionConfig config)
bool isFinished() const override
Motion(MotionContext ctx)
Definition motion.hpp:35