PX4 Firmware
PX4 Autopilot Software http://px4.io
FlightTaskOrbit.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2018-2019 PX4 Development Team. 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 PX4 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 FlightTaskOrbit.cpp
36  */
37 
38 #include "FlightTaskOrbit.hpp"
39 
40 #include <mathlib/mathlib.h>
41 #include <lib/ecl/geo/geo.h>
42 
43 using namespace matrix;
44 
45 FlightTaskOrbit::FlightTaskOrbit() : _circle_approach_line(_position)
46 {
47  _sticks_data_required = false;
48 }
49 
51 {
52  bool ret = true;
53  // save previous velocity and roatation direction
54  float v = fabsf(_v);
55  bool clockwise = _v > 0;
56 
57  // commanded radius
58  if (PX4_ISFINITE(command.param1)) {
59  clockwise = command.param1 > 0;
60  const float r = fabsf(command.param1);
61  ret = ret && setRadius(r);
62  }
63 
64  // commanded velocity, take sign of radius as rotation direction
65  if (PX4_ISFINITE(command.param2)) {
66  v = command.param2;
67  }
68 
69  ret = ret && setVelocity(v * (clockwise ? 1.f : -1.f));
70 
71  // TODO: apply x,y / z independently in geo library
72  // commanded center coordinates
73  // if(PX4_ISFINITE(command.param5) && PX4_ISFINITE(command.param6)) {
74  // map_projection_global_project(command.param5, command.param6, &_center(0), &_center(1));
75  // }
76 
77  // commanded altitude
78  // if(PX4_ISFINITE(command.param7)) {
79  // _position_setpoint(2) = gl_ref.alt - command.param7;
80  // }
81 
82  if (PX4_ISFINITE(command.param5) && PX4_ISFINITE(command.param6) && PX4_ISFINITE(command.param7)) {
83  if (globallocalconverter_tolocal(command.param5, command.param6, command.param7, &_center(0), &_center(1),
84  &_position_setpoint(2))) {
85  // global to local conversion failed
86  ret = false;
87  }
88  }
89 
90  // perpendicularly approach the orbit circle again when new parameters get commanded
91  _in_circle_approach = true;
92 
93  return ret;
94 }
95 
97 {
98  orbit_status_s orbit_status{};
99  orbit_status.timestamp = hrt_absolute_time();
100  orbit_status.radius = math::signNoZero(_v) * _r;
101  orbit_status.frame = 0; // MAV_FRAME::MAV_FRAME_GLOBAL
102 
103  if (globallocalconverter_toglobal(_center(0), _center(1), _position_setpoint(2), &orbit_status.x, &orbit_status.y,
104  &orbit_status.z)) {
105  return false; // don't send the message if the transformation failed
106  }
107 
108  _orbit_status_pub.publish(orbit_status);
109 
110  return true;
111 }
112 
114 {
115  // clip the radius to be within range
117 
118  // small radius is more important than high velocity for safety
120  _v = math::sign(_v) * sqrtf(_acceleration_max * r);
121  }
122 
123  _r = r;
124  return true;
125 }
126 
127 bool FlightTaskOrbit::setVelocity(const float v)
128 {
129  if (fabs(v) < _velocity_max &&
131  _v = v;
132  return true;
133  }
134 
135  return false;
136 }
137 
138 bool FlightTaskOrbit::checkAcceleration(float r, float v, float a)
139 {
140  return v * v < a * r;
141 }
142 
144 {
145  bool ret = FlightTaskManualAltitudeSmooth::activate(last_setpoint);
146  _r = _radius_min;
147  _v = 1.f;
149  _center(0) -= _r;
150 
151  // need a valid position and velocity
152  ret = ret && PX4_ISFINITE(_position(0))
153  && PX4_ISFINITE(_position(1))
154  && PX4_ISFINITE(_position(2))
155  && PX4_ISFINITE(_velocity(0))
156  && PX4_ISFINITE(_velocity(1))
157  && PX4_ISFINITE(_velocity(2));
158 
159  return ret;
160 }
161 
163 {
164  // update altitude
166 
167  // stick input adjusts parameters within a fixed time frame
168  const float r = _r - _sticks_expo(0) * _deltatime * (_radius_max / 8.f);
169  const float v = _v - _sticks_expo(1) * _deltatime * (_velocity_max / 4.f);
170 
171  setRadius(r);
172  setVelocity(v);
173 
174  Vector2f center_to_position = Vector2f(_position) - _center;
175 
176  // make vehicle front always point towards the center
177  _yaw_setpoint = atan2f(center_to_position(1), center_to_position(0)) + M_PI_F;
178 
179  if (_in_circle_approach) {
181 
182  } else {
183  generate_circle_setpoints(center_to_position);
184  }
185 
186  // publish information to UI
187  sendTelemetry();
188 
189  return true;
190 }
191 
193 {
195  // calculate target point on circle and plan a line trajectory
196  Vector2f start_to_center = _center - Vector2f(_position);
197  Vector2f start_to_circle = (start_to_center.norm() - _r) * start_to_center.unit_or_zero();
198  Vector2f closest_circle_point = Vector2f(_position) + start_to_circle;
199  Vector3f target = Vector3f(closest_circle_point(0), closest_circle_point(1), _position(2));
201  _circle_approach_line.setSpeed(_param_mpc_xy_cruise.get());
202  }
203 
204  // follow the planned line and switch to orbiting once the circle is reached
207 
208  // yaw stays constant
209  _yawspeed_setpoint = NAN;
210 }
211 
213 {
214  // xy velocity to go around in a circle
215  Vector2f velocity_xy(-center_to_position(1), center_to_position(0));
216  velocity_xy = velocity_xy.unit_or_zero();
217  velocity_xy *= _v;
218 
219  // xy velocity adjustment to stay on the radius distance
220  velocity_xy += (_r - center_to_position.norm()) * center_to_position.unit_or_zero();
221 
222  _velocity_setpoint(0) = velocity_xy(0);
223  _velocity_setpoint(1) = velocity_xy(1);
225 
226  // yawspeed feed-forward because we know the necessary angular rate
228 }
bool activate(vehicle_local_position_setpoint_s last_setpoint) override
Call once on the event where you switch to the task.
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
Definition: Limits.hpp:66
matrix::Vector3f _velocity
current vehicle velocity
Definition: FlightTask.hpp:208
float _yawspeed_setpoint
Definition: FlightTask.hpp:226
void generate_circle_setpoints(matrix::Vector2f center_to_position)
generates xy setpoints to orbit the vehicle
float _yaw_setpoint
Definition: FlightTask.hpp:225
Flight task for orbiting in a circle around a target position.
uint64_t timestamp
Definition: orbit_status.h:53
Definition of geo / math functions to perform geodesic calculations.
float _deltatime
passed time in seconds since the task was last updated
Definition: FlightTask.hpp:201
uORB::Publication< orbit_status_s > _orbit_status_pub
bool checkAcceleration(float r, float v, float a)
Check the feasibility of orbit parameters with respect to centripetal acceleration a = v^2 / r...
int signNoZero(T val)
Definition: Functions.hpp:56
bool sendTelemetry()
Send out telemetry information for the log and MAVLink.
bool update() override
To be called regularly in the control loop cycle to execute the task.
const float _radius_min
bool setVelocity(const float v)
Change the velocity of the vehicle on the circle.
bool update() override
To be called regularly in the control loop cycle to execute the task.
matrix::Vector3f _position_setpoint
Setpoints which the position controller has to execute.
Definition: FlightTask.hpp:220
float _r
radius with which to orbit the target
void setLineFromTo(const matrix::Vector3f &start, const matrix::Vector3f &end)
const float _acceleration_max
bool publish(const T &data)
Publish the struct.
Definition: Publication.hpp:68
matrix::Vector< float, 4 > _sticks_expo
modified manual sticks using expo function
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
Vector2< float > Vector2f
Definition: Vector2.hpp:69
matrix::Vector3f _position
current vehicle position
Definition: FlightTask.hpp:207
matrix::Vector3f _velocity_setpoint
Definition: FlightTask.hpp:221
void generate_circle_approach_setpoints()
generates setpoints to smoothly reach the closest point on the circle when starting from far away ...
const float _radius_max
bool applyCommandParameters(const vehicle_command_s &command) override
To be called to adopt parameters from an arrived vehicle command.
float _v
clockwise tangential velocity for orbiting in m/s
bool activate(vehicle_local_position_setpoint_s last_setpoint) override
Call once on the event where you switch to the task.
bool setRadius(const float r)
Change the radius of the circle.
int sign(T val)
Definition: Functions.hpp:49
Vector3< float > Vector3f
Definition: Vector3.hpp:136
int globallocalconverter_toglobal(float x, float y, float z, double *lat, double *lon, float *alt)
Convert from local position coordinates to global position coordinates using the global reference...
Definition: geo.cpp:241
bool isEndReached()
Check if the end was reached.
int globallocalconverter_tolocal(double lat, double lon, float alt, float *x, float *y, float *z)
Convert from global position coordinates to local position coordinates using the global reference...
Definition: geo.cpp:229
const float _velocity_max
StraightLine _circle_approach_line
#define M_PI_F
Definition: ashtech.cpp:44
Type norm() const
Definition: Vector.hpp:73
Vector unit_or_zero(const Type eps=Type(1e-5)) const
Definition: Vector.hpp:95
void setSpeed(const float &speed)
matrix::Vector2f _center
local frame coordinates of the center point
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
void generateSetpoints(matrix::Vector3f &position_setpoint, matrix::Vector3f &velocity_setpoint)
Generate setpoints on a straight line according to parameters.
bool _sticks_data_required
let inherited task-class define if it depends on stick data