PX4 Firmware
PX4 Autopilot Software http://px4.io
ecl_l1_pos_controller.h
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2013 Estimation and Control Library (ECL). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name ECL nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file ecl_l1_pos_control.h
36  * Implementation of L1 position control.
37  *
38  *
39  * Acknowledgements and References:
40  *
41  * This implementation has been built for PX4 based on the original
42  * publication from [1] and does include a lot of the ideas (not code)
43  * from [2].
44  *
45  *
46  * [1] S. Park, J. Deyst, and J. P. How, "A New Nonlinear Guidance Logic for Trajectory Tracking,"
47  * Proceedings of the AIAA Guidance, Navigation and Control
48  * Conference, Aug 2004. AIAA-2004-4900.
49  *
50  * [2] Paul Riseborough, Brandon Jones and Andrew Tridgell, L1 control for APM. Aug 2013.
51  * - Explicit control over frequency and damping
52  * - Explicit control over track capture angle
53  * - Ability to use loiter radius smaller than L1 length
54  * - Modified to use PD control for circle tracking to enable loiter radius less than L1 length
55  * - Modified to enable period and damping of guidance loop to be set explicitly
56  * - Modified to provide explicit control over capture angle
57  *
58  */
59 
60 #ifndef ECL_L1_POS_CONTROLLER_H
61 #define ECL_L1_POS_CONTROLLER_H
62 
63 #include <mathlib/mathlib.h>
64 #include <matrix/math.hpp>
65 #include <geo/geo.h>
66 #include <ecl.h>
67 
68 /**
69  * L1 Nonlinear Guidance Logic
70  */
72 {
73 public:
74  /**
75  * The current target bearing
76  *
77  * @return bearing angle (-pi..pi, in NED frame)
78  */
80 
81  /**
82  * Get lateral acceleration demand.
83  *
84  * @return Lateral acceleration in m/s^2
85  */
87 
88  /**
89  * Heading error.
90  *
91  * The heading error is either compared to the current track
92  * or to the tangent of the current loiter radius.
93  */
94  float bearing_error() { return _bearing_error; }
95 
96  /**
97  * Bearing from aircraft to current target.
98  *
99  * @return bearing angle (-pi..pi, in NED frame)
100  */
101  float target_bearing() { return _target_bearing; }
102 
103  /**
104  * Get roll angle setpoint for fixed wing.
105  *
106  * @return Roll angle (in NED frame)
107  */
109 
110  /**
111  * Get the current crosstrack error.
112  *
113  * @return Crosstrack error in meters.
114  */
116 
117  /**
118  * Returns true if the loiter waypoint has been reached
119  */
121 
122  /**
123  * Returns true if following a circle (loiter)
124  */
125  bool circle_mode() { return _circle_mode; }
126 
127  /**
128  * Get the switch distance
129  *
130  * This is the distance at which the system will
131  * switch to the next waypoint. This depends on the
132  * period and damping
133  *
134  * @param waypoint_switch_radius The switching radius the waypoint has set.
135  */
136  float switch_distance(float waypoint_switch_radius);
137 
138  /**
139  * Navigate between two waypoints
140  *
141  * Calling this function with two waypoints results in the
142  * control outputs to fly to the line segment defined by
143  * the points and once captured following the line segment.
144  * This follows the logic in [1].
145  *
146  * @return sets _lateral_accel setpoint
147  */
148  void navigate_waypoints(const matrix::Vector2f &vector_A, const matrix::Vector2f &vector_B,
149  const matrix::Vector2f &vector_curr_position, const matrix::Vector2f &ground_speed);
150 
151  /**
152  * Navigate on an orbit around a loiter waypoint.
153  *
154  * This allow orbits smaller than the L1 length,
155  * this modification was introduced in [2].
156  *
157  * @return sets _lateral_accel setpoint
158  */
159  void navigate_loiter(const matrix::Vector2f &vector_A, const matrix::Vector2f &vector_curr_position, float radius,
160  int8_t loiter_direction, const matrix::Vector2f &ground_speed_vector);
161 
162  /**
163  * Navigate on a fixed bearing.
164  *
165  * This only holds a certain direction and does not perform cross
166  * track correction. Helpful for semi-autonomous modes. Introduced
167  * by [2].
168  *
169  * @return sets _lateral_accel setpoint
170  */
171  void navigate_heading(float navigation_heading, float current_heading, const matrix::Vector2f &ground_speed);
172 
173  /**
174  * Keep the wings level.
175  *
176  * This is typically needed for maximum-lift-demand situations,
177  * such as takeoff or near stall. Introduced in [2].
178  */
179  void navigate_level_flight(float current_heading);
180 
181  /**
182  * Set the L1 period.
183  */
184  void set_l1_period(float period);
185 
186  /**
187  * Set the L1 damping factor.
188  *
189  * The original publication recommends a default of sqrt(2) / 2 = 0.707
190  */
191  void set_l1_damping(float damping);
192 
193  /**
194  * Set the maximum roll angle output in radians
195  */
196  void set_l1_roll_limit(float roll_lim_rad) { _roll_lim_rad = roll_lim_rad; }
197 
198  /**
199  * Set roll angle slew rate. Set to zero to deactivate.
200  */
201  void set_roll_slew_rate(float roll_slew_rate) { _roll_slew_rate = roll_slew_rate; }
202 
203  /**
204  * Set control loop dt. The value will be used to apply roll angle setpoint slew rate limiting.
205  */
206  void set_dt(float dt) { _dt = dt;}
207 
208 private:
209 
210  float _lateral_accel{0.0f}; ///< Lateral acceleration setpoint in m/s^2
211  float _L1_distance{20.0f}; ///< L1 lead distance, defined by period and damping
212  bool _circle_mode{false}; ///< flag for loiter mode
213  float _nav_bearing{0.0f}; ///< bearing to L1 reference point
214  float _bearing_error{0.0f}; ///< bearing error
215  float _crosstrack_error{0.0f}; ///< crosstrack error in meters
216  float _target_bearing{0.0f}; ///< the heading setpoint
217 
218  float _L1_period{25.0f}; ///< L1 tracking period in seconds
219  float _L1_damping{0.75f}; ///< L1 damping ratio
220  float _L1_ratio{5.0f}; ///< L1 ratio for navigation
221  float _K_L1{2.0f}; ///< L1 control gain for _L1_damping
222  float _heading_omega{1.0f}; ///< Normalized frequency
223 
224  float _roll_lim_rad{math::radians(30.0f)}; ///<maximum roll angle in radians
225  float _roll_setpoint{0.0f}; ///< current roll angle setpoint in radians
226  float _roll_slew_rate{0.0f}; ///< roll angle setpoint slew rate limit in rad/s
227  float _dt{0}; ///< control loop time in seconds
228 
229  /**
230  * Convert a 2D vector from WGS84 to planar coordinates.
231  *
232  * This converts from latitude and longitude to planar
233  * coordinates with (0,0) being at the position of ref and
234  * returns a vector in meters towards wp.
235  *
236  * @param ref The reference position in WGS84 coordinates
237  * @param wp The point to convert to into the local coordinates, in WGS84 coordinates
238  * @return The vector in meters pointing from the reference position to the coordinates
239  */
241 
242  /**
243  * Update roll angle setpoint. This will also apply slew rate limits if set.
244  *
245  */
246  void update_roll_setpoint();
247 
248 };
249 
250 
251 #endif /* ECL_L1_POS_CONTROLLER_H */
Adapter / shim layer for system calls needed by ECL.
float nav_bearing()
The current target bearing.
bool circle_mode()
Returns true if following a circle (loiter)
void set_l1_damping(float damping)
Set the L1 damping factor.
float _dt
control loop time in seconds
Definition of geo / math functions to perform geodesic calculations.
float _roll_slew_rate
roll angle setpoint slew rate limit in rad/s
L1 Nonlinear Guidance Logic.
float _K_L1
L1 control gain for _L1_damping.
bool _circle_mode
flag for loiter mode
float switch_distance(float waypoint_switch_radius)
Get the switch distance.
void update_roll_setpoint()
Update roll angle setpoint.
float _target_bearing
the heading setpoint
void navigate_loiter(const matrix::Vector2f &vector_A, const matrix::Vector2f &vector_curr_position, float radius, int8_t loiter_direction, const matrix::Vector2f &ground_speed_vector)
Navigate on an orbit around a loiter waypoint.
void set_roll_slew_rate(float roll_slew_rate)
Set roll angle slew rate.
float crosstrack_error()
Get the current crosstrack error.
float _nav_bearing
bearing to L1 reference point
float target_bearing()
Bearing from aircraft to current target.
float _L1_ratio
L1 ratio for navigation.
constexpr T radians(T degrees)
Definition: Limits.hpp:85
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
float _L1_distance
L1 lead distance, defined by period and damping.
float nav_lateral_acceleration_demand()
Get lateral acceleration demand.
float _roll_lim_rad
maximum roll angle in radians
void set_l1_period(float period)
Set the L1 period.
void set_dt(float dt)
Set control loop dt.
float bearing_error()
Heading error.
Type wrap_pi(Type x)
Wrap value in range [-π, π)
void navigate_waypoints(const matrix::Vector2f &vector_A, const matrix::Vector2f &vector_B, const matrix::Vector2f &vector_curr_position, const matrix::Vector2f &ground_speed)
Navigate between two waypoints.
void set_l1_roll_limit(float roll_lim_rad)
Set the maximum roll angle output in radians.
float _heading_omega
Normalized frequency.
float dt
Definition: px4io.c:73
float _bearing_error
bearing error
float _crosstrack_error
crosstrack error in meters
float get_roll_setpoint()
Get roll angle setpoint for fixed wing.
float _roll_setpoint
current roll angle setpoint in radians
void navigate_level_flight(float current_heading)
Keep the wings level.
bool reached_loiter_target()
Returns true if the loiter waypoint has been reached.
float _L1_damping
L1 damping ratio.
void navigate_heading(float navigation_heading, float current_heading, const matrix::Vector2f &ground_speed)
Navigate on a fixed bearing.
float _L1_period
L1 tracking period in seconds.
matrix::Vector2f get_local_planar_vector(const matrix::Vector2f &origin, const matrix::Vector2f &target) const
Convert a 2D vector from WGS84 to planar coordinates.
float _lateral_accel
Lateral acceleration setpoint in m/s^2.