PX4 Firmware
PX4 Autopilot Software http://px4.io
vtol_type.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2015 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 vtol_type.cpp
36 *
37 * @author Roman Bapst <bapstroman@gmail.com>
38 * @author Andreas Antener <andreas@uaventure.com>
39 *
40 */
41 
42 #include "vtol_type.h"
43 #include "vtol_att_control_main.h"
44 
45 #include <float.h>
46 #include <px4_platform_common/defines.h>
47 #include <matrix/math.hpp>
48 
49 
51  _attc(att_controller),
52  _vtol_mode(mode::ROTARY_WING)
53 {
54  _v_att = _attc->get_att();
70 
71  for (auto &pwm_max : _max_mc_pwm_values.values) {
72  pwm_max = PWM_DEFAULT_MAX;
73  }
74 
75  for (auto &pwm_disarmed : _disarmed_pwm_values.values) {
76  pwm_disarmed = PWM_MOTOR_OFF;
77  }
78 }
79 
81 {
82  const char *dev = PWM_OUTPUT0_DEVICE_PATH;
83  int fd = px4_open(dev, 0);
84 
85  if (fd < 0) {
86  PX4_ERR("can't open %s", dev);
87  return false;
88  }
89 
90  int ret = px4_ioctl(fd, PWM_SERVO_GET_MAX_PWM, (long unsigned int)&_max_mc_pwm_values);
91 
92 
93  if (ret != PX4_OK) {
94  PX4_ERR("failed getting max values");
95  px4_close(fd);
96  return false;
97  }
98 
99  ret = px4_ioctl(fd, PWM_SERVO_GET_MIN_PWM, (long unsigned int)&_min_mc_pwm_values);
100 
101  if (ret != PX4_OK) {
102  PX4_ERR("failed getting min values");
103  px4_close(fd);
104  return false;
105  }
106 
107  ret = px4_ioctl(fd, PWM_SERVO_GET_DISARMED_PWM, (long unsigned int)&_disarmed_pwm_values);
108 
109  if (ret != PX4_OK) {
110  PX4_ERR("failed getting disarmed values");
111  px4_close(fd);
112  return false;
113  }
114 
115  px4_close(fd);
116 
117  return true;
118 
119 }
120 
122 {
123  if (!flag_idle_mc) {
125  }
126 
129  }
130 
131  // copy virtual attitude setpoint to real attitude setpoint
133 
134  _mc_roll_weight = 1.0f;
135  _mc_pitch_weight = 1.0f;
136  _mc_yaw_weight = 1.0f;
137  _mc_throttle_weight = 1.0f;
138 }
139 
141 {
142  if (flag_idle_mc) {
144  }
145 
148  }
149 
150  // copy virtual attitude setpoint to real attitude setpoint
152  _mc_roll_weight = 0.0f;
153  _mc_pitch_weight = 0.0f;
154  _mc_yaw_weight = 0.0f;
155 
156  // tecs didn't publish an update yet after the transition
158  _tecs_running = false;
159 
160  } else if (!_tecs_running) {
161  _tecs_running = true;
163  }
164 
165  // TECS didn't publish yet or the position controller didn't publish yet AFTER tecs
166  // only wait on TECS we're in a mode where it is actually running
169 
170  waiting_on_tecs();
171  }
172 
174 }
175 
177 {
179 }
180 
182 {
184 }
185 
187 {
188 
191 
192  // fixed-wing minimum altitude
193  if (_params->fw_min_alt > FLT_EPSILON) {
194 
195  if (-(_local_pos->z) < _params->fw_min_alt) {
196  _attc->abort_front_transition("QuadChute: Minimum altitude breached");
197  }
198  }
199 
200  // adaptive quadchute
202 
203  // We use tecs for tracking in FW and local_pos_sp during transitions
204  if (_tecs_running) {
205  // 1 second rolling average
206  _ra_hrate = (49 * _ra_hrate + _tecs_status->height_rate) / 50;
208 
209  // are we dropping while requesting significant ascend?
211  (_ra_hrate < -1.0f) &&
212  (_ra_hrate_sp > 1.0f)) {
213 
214  _attc->abort_front_transition("QuadChute: loss of altitude");
215  }
216 
217  } else {
218  const bool height_error = _local_pos->z_valid && ((-_local_pos_sp->z - -_local_pos->z) > _params->fw_alt_err);
219  const bool height_rate_error = _local_pos->v_z_valid && (_local_pos->vz > 1.0f) && (_local_pos->z_deriv > 1.0f);
220 
221  if (height_error && height_rate_error) {
222  _attc->abort_front_transition("QuadChute: large altitude error");
223  }
224  }
225  }
226 
227  // fixed-wing maximum pitch angle
228  if (_params->fw_qc_max_pitch > 0) {
229 
230  if (fabsf(euler.theta()) > fabsf(math::radians(_params->fw_qc_max_pitch))) {
231  _attc->abort_front_transition("Maximum pitch angle exceeded");
232  }
233  }
234 
235  // fixed-wing maximum roll angle
236  if (_params->fw_qc_max_roll > 0) {
237 
238  if (fabsf(euler.phi()) > fabsf(math::radians(_params->fw_qc_max_roll))) {
239  _attc->abort_front_transition("Maximum roll angle exceeded");
240  }
241  }
242  }
243 }
244 
246 {
247  unsigned pwm_value = _params->idle_pwm_mc;
248  struct pwm_output_values pwm_values {};
249 
250  for (int i = 0; i < num_outputs_max; i++) {
252  pwm_values.values[i] = pwm_value;
253 
254  } else {
255  pwm_values.values[i] = _min_mc_pwm_values.values[i];
256  }
257 
258  pwm_values.channel_count++;
259  }
260 
262 }
263 
265 {
266  struct pwm_output_values pwm_values {};
267 
268  for (int i = 0; i < num_outputs_max; i++) {
270  pwm_values.values[i] = PWM_MOTOR_OFF;
271 
272  } else {
273  pwm_values.values[i] = _min_mc_pwm_values.values[i];
274  }
275 
276  pwm_values.channel_count++;
277  }
278 
280 }
281 
283 {
284  const char *dev = PWM_OUTPUT0_DEVICE_PATH;
285  int fd = px4_open(dev, 0);
286 
287  if (fd < 0) {
288  PX4_WARN("can't open %s", dev);
289  return false;
290  }
291 
292  int ret;
293 
294  if (type == pwm_limit_type::TYPE_MINIMUM) {
295  ret = px4_ioctl(fd, PWM_SERVO_SET_MIN_PWM, (long unsigned int)&pwm_values);
296 
297  } else {
298  ret = px4_ioctl(fd, PWM_SERVO_SET_MAX_PWM, (long unsigned int)&pwm_values);
299  }
300 
301  px4_close(fd);
302 
303 
304  if (ret != OK) {
305  PX4_DEBUG("failed setting max values");
306  return false;
307  }
308 
309  return true;
310 }
311 
312 motor_state VtolType::set_motor_state(const motor_state current_state, const motor_state next_state, const int value)
313 {
314  struct pwm_output_values pwm_values = {};
315  pwm_values.channel_count = num_outputs_max;
316 
317  // per default all motors are running
318  for (int i = 0; i < num_outputs_max; i++) {
319  pwm_values.values[i] = _max_mc_pwm_values.values[i];
320  }
321 
322  switch (next_state) {
324  break;
325 
327  for (int i = 0; i < num_outputs_max; i++) {
329  pwm_values.values[i] = _disarmed_pwm_values.values[i];
330  }
331  }
332 
333  break;
334 
335  case motor_state::IDLE:
336 
337  for (int i = 0; i < num_outputs_max; i++) {
339  pwm_values.values[i] = _params->idle_pwm_mc;
340  }
341  }
342 
343  break;
344 
345  case motor_state::VALUE:
346  for (int i = 0; i < num_outputs_max; i++) {
348  pwm_values.values[i] = value;
349  }
350  }
351 
352  break;
353  }
354 
356  return next_state;
357 
358  } else {
359  return current_state;
360  }
361 }
362 
363 bool VtolType::is_channel_set(const int channel, const int target)
364 {
365  int channel_bitmap = 0;
366 
367  int tmp;
368  int channels = target;
369 
370 
371  for (int i = 0; i < num_outputs_max; ++i) {
372  tmp = channels % 10;
373 
374  if (tmp == 0) {
375  break;
376  }
377 
378  channel_bitmap |= 1 << (tmp - 1);
379  channels = channels / 10;
380  }
381 
382  return (channel_bitmap >> channel) & 1;
383 }
#define PWM_DEFAULT_MAX
Default maximum PWM in us.
hrt_abstime _trans_finished_ts
Definition: vtol_type.h:212
bool _tecs_running
Definition: vtol_type.h:214
struct vehicle_attitude_setpoint_s * get_mc_virtual_att_sp()
struct vehicle_local_position_setpoint_s * _local_pos_sp
Definition: vtol_type.h:189
motor_state _motor_state
Definition: vtol_type.h:217
float fw_qc_max_pitch
Definition: vtol_type.h:57
Type theta() const
Definition: Euler.hpp:132
float _mc_pitch_weight
Definition: vtol_type.h:200
bool is_channel_set(const int channel, const int target)
Determines if channel is set in target.
Definition: vtol_type.cpp:363
float fw_alt_err
Definition: vtol_type.h:56
VtolType(VtolAttitudeControl *att_controller)
Definition: vtol_type.cpp:50
float height_rate
Definition: tecs_status.h:64
float _mc_yaw_weight
Definition: vtol_type.h:201
int32_t fw_motors_off
bitmask of all motors that should be off in fixed wing mode
Definition: vtol_type.h:70
bool set_idle_fw()
Sets mc motor minimum pwm to PWM_MIN which ensures that the motors stop spinning on zero throttle in ...
Definition: vtol_type.cpp:264
struct actuator_controls_s * _actuators_mc_in
Definition: vtol_type.h:186
#define PWM_SERVO_GET_DISARMED_PWM
get the PWM value when disarmed
struct tecs_status_s * _tecs_status
Definition: vtol_type.h:191
struct vehicle_attitude_s * _v_att
Definition: vtol_type.h:178
float fw_min_alt
Definition: vtol_type.h:55
float altitude_sp
Definition: tecs_status.h:61
struct vehicle_attitude_setpoint_s * get_fw_virtual_att_sp()
Type phi() const
Definition: Euler.hpp:128
#define FLT_EPSILON
struct vehicle_land_detected_s * get_land_detected()
VtolAttitudeControl * _attc
Definition: vtol_type.h:173
struct vehicle_local_position_s * get_local_pos()
struct Params * _params
Definition: vtol_type.h:194
motor_state
Definition: vtol_type.h:93
struct actuator_controls_s * _actuators_out_0
Definition: vtol_type.h:184
hrt_abstime _tecs_running_ts
Definition: vtol_type.h:215
float _ra_hrate
Definition: vtol_type.h:207
#define PWM_OUTPUT0_DEVICE_PATH
uint16_t values[PWM_OUTPUT_MAX_CHANNELS]
struct vehicle_local_position_setpoint_s * get_local_pos_sp()
struct vehicle_local_position_s * _local_pos
Definition: vtol_type.h:188
virtual void update_fw_state()
Update fixed wing state.
Definition: vtol_type.cpp:140
struct actuator_controls_s * _actuators_fw_in
Definition: vtol_type.h:187
float _mc_throttle_weight
Definition: vtol_type.h:202
struct vehicle_attitude_setpoint_s * _v_att_sp
Definition: vtol_type.h:179
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
uint32_t channel_count
pwm_limit_type
Used to specify if min or max pwm values should be altered.
Definition: vtol_type.h:103
bool apply_pwm_limits(struct pwm_output_values &pwm_values, pwm_limit_type type)
Adjust minimum/maximum pwm values for the output channels.
Definition: vtol_type.cpp:282
static constexpr const int num_outputs_max
Definition: vtol_type.h:176
struct vehicle_attitude_setpoint_s * get_att_sp()
struct vehicle_attitude_setpoint_s * _mc_virtual_att_sp
Definition: vtol_type.h:180
bool set_idle_mc()
Sets mc motor minimum pwm to VT_IDLE_PWM_MC which ensures that they are spinning in mc mode...
Definition: vtol_type.cpp:245
Euler angles class.
Definition: AxisAngle.hpp:18
motor_state set_motor_state(const motor_state current_state, const motor_state next_state, const int value=0)
Sets state of a selection of motors, see struct motor_state.
Definition: vtol_type.cpp:312
struct vehicle_attitude_setpoint_s * _fw_virtual_att_sp
Definition: vtol_type.h:181
struct vtol_vehicle_status_s * get_vtol_vehicle_status()
bool flag_idle_mc
Definition: vtol_type.h:196
int fd
Definition: dataman.cpp:146
#define PWM_SERVO_SET_MIN_PWM
set the minimum PWM value the output will send
struct actuator_controls_s * get_actuators_out1()
struct actuator_controls_s * get_actuators_mc_in()
struct vehicle_control_mode_s * get_control_mode()
float altitude_filtered
Definition: tecs_status.h:62
struct vehicle_control_mode_s * _v_control_mode
Definition: vtol_type.h:182
bool init()
Initialise.
Definition: vtol_type.cpp:80
struct Params * get_params()
float _ra_hrate_sp
Definition: vtol_type.h:208
#define PWM_SERVO_SET_MAX_PWM
set the maximum PWM value the output will send
float _mc_roll_weight
Definition: vtol_type.h:199
int px4_open(const char *path, int flags,...)
struct actuator_controls_s * get_actuators_out0()
struct actuator_controls_s * get_actuators_fw_in()
uint64_t timestamp
Definition: tecs_status.h:60
void check_quadchute_condition()
Checks for fixed-wing failsafe condition and issues abort request if needed.
Definition: vtol_type.cpp:186
Quaternion< float > Quatf
Definition: Quaternion.hpp:544
#define PWM_SERVO_GET_MIN_PWM
get the minimum PWM value the output will send
virtual void update_mc_state()
Update multicopter state.
Definition: vtol_type.cpp:121
float height_rate_setpoint
Definition: tecs_status.h:63
struct vehicle_attitude_s * get_att()
struct airspeed_validated_s * _airspeed_validated
Definition: vtol_type.h:190
float fw_qc_max_roll
Definition: vtol_type.h:58
virtual void update_transition_state()=0
Update transition state.
Definition: vtol_type.cpp:176
struct tecs_status_s * get_tecs_status()
#define PWM_MOTOR_OFF
Default value for a shutdown motor.
struct actuator_controls_s * _actuators_out_1
Definition: vtol_type.h:185
#define OK
Definition: uavcan_main.cpp:71
Stores the max pwm values given by the system.
Definition: vtol_type.h:256
struct vehicle_land_detected_s * _land_detected
Definition: vtol_type.h:192
void abort_front_transition(const char *reason)
mode
Definition: vtol_type.h:76
struct vtol_vehicle_status_s * _vtol_vehicle_status
Definition: vtol_type.h:183
int32_t vtol_motor_id
Definition: vtol_type.h:52
int32_t idle_pwm_mc
Definition: vtol_type.h:51
bool can_transition_on_ground()
Returns true if we&#39;re allowed to do a mode transition on the ground.
Definition: vtol_type.cpp:181
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
struct airspeed_validated_s * get_airspeed()
int px4_close(int fd)
#define PWM_SERVO_GET_MAX_PWM
get the maximum PWM value the output will send
virtual void waiting_on_tecs()
Special handling opportunity for the time right after transition to FW before TECS is running...
Definition: vtol_type.h:154
int px4_ioctl(int fd, int cmd, unsigned long arg)