PX4 Firmware
PX4 Autopilot Software http://px4.io
tiltrotor.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 tiltrotor.cpp
36  *
37  * @author Roman Bapst <bapstroman@gmail.com>
38  * @author Andreas Antener <andreas@uaventure.com>
39  *
40 */
41 
42 #include "tiltrotor.h"
43 #include "vtol_att_control_main.h"
44 
45 #define ARSP_YAW_CTRL_DISABLE 7.0f // airspeed at which we stop controlling yaw during a front transition
46 
48  VtolType(attc)
49 {
50  _vtol_schedule.flight_mode = vtol_mode::MC_MODE;
51  _vtol_schedule.transition_start = 0;
52 
53  _mc_roll_weight = 1.0f;
54  _mc_pitch_weight = 1.0f;
55  _mc_yaw_weight = 1.0f;
56 
58 
59  _params_handles_tiltrotor.tilt_mc = param_find("VT_TILT_MC");
60  _params_handles_tiltrotor.tilt_transition = param_find("VT_TILT_TRANS");
61  _params_handles_tiltrotor.tilt_fw = param_find("VT_TILT_FW");
62  _params_handles_tiltrotor.front_trans_dur_p2 = param_find("VT_TRANS_P2_DUR");
63 }
64 
65 void
67 {
68  float v;
69 
70  /* vtol tilt mechanism position in mc mode */
72  _params_tiltrotor.tilt_mc = v;
73 
74  /* vtol tilt mechanism position in transition mode */
75  param_get(_params_handles_tiltrotor.tilt_transition, &v);
76  _params_tiltrotor.tilt_transition = v;
77 
78  /* vtol tilt mechanism position in fw mode */
80  _params_tiltrotor.tilt_fw = v;
81 
82  /* vtol front transition phase 2 duration */
83  param_get(_params_handles_tiltrotor.front_trans_dur_p2, &v);
84  _params_tiltrotor.front_trans_dur_p2 = v;
85 }
86 
88 {
89  /* simple logic using a two way switch to perform transitions.
90  * after flipping the switch the vehicle will start tilting rotors, picking up
91  * forward speed. After the vehicle has picked up enough speed the rotors are tilted
92  * forward completely. For the backtransition the motors simply rotate back.
93  */
94 
96 
97  // plane is in multicopter mode
98  switch (_vtol_schedule.flight_mode) {
99  case vtol_mode::MC_MODE:
100  break;
101 
102  case vtol_mode::FW_MODE:
104  _vtol_schedule.transition_start = hrt_absolute_time();
105  break;
106 
108  // failsafe into multicopter mode
109  _vtol_schedule.flight_mode = vtol_mode::MC_MODE;
110  break;
111 
113  // failsafe into multicopter mode
114  _vtol_schedule.flight_mode = vtol_mode::MC_MODE;
115  break;
116 
118  float time_since_trans_start = (float)(hrt_absolute_time() - _vtol_schedule.transition_start) * 1e-6f;
119 
120  if (_tilt_control <= _params_tiltrotor.tilt_mc && time_since_trans_start > _params->back_trans_duration) {
121  _vtol_schedule.flight_mode = vtol_mode::MC_MODE;
122  }
123 
124  break;
125  }
126 
127  } else {
128 
129  switch (_vtol_schedule.flight_mode) {
130  case vtol_mode::MC_MODE:
131  // initialise a front transition
133  _vtol_schedule.transition_start = hrt_absolute_time();
134  break;
135 
136  case vtol_mode::FW_MODE:
137  break;
138 
140 
141  float time_since_trans_start = (float)(hrt_absolute_time() - _vtol_schedule.transition_start) * 1e-6f;
142 
143  const bool airspeed_triggers_transition = PX4_ISFINITE(_airspeed_validated->equivalent_airspeed_m_s)
145 
146  bool transition_to_p2 = false;
147 
148  if (time_since_trans_start > _params->front_trans_time_min) {
149  if (airspeed_triggers_transition) {
151 
152  } else {
153  transition_to_p2 = _tilt_control >= _params_tiltrotor.tilt_transition &&
154  time_since_trans_start > _params->front_trans_time_openloop;;
155  }
156  }
157 
158  transition_to_p2 |= can_transition_on_ground();
159 
160  if (transition_to_p2) {
162  _vtol_schedule.transition_start = hrt_absolute_time();
163  }
164 
165  break;
166  }
167 
169 
170  // if the rotors have been tilted completely we switch to fw mode
171  if (_tilt_control >= _params_tiltrotor.tilt_fw) {
172  _vtol_schedule.flight_mode = vtol_mode::FW_MODE;
174  }
175 
176  break;
177 
179  // failsafe into fixed wing mode
180  _vtol_schedule.flight_mode = vtol_mode::FW_MODE;
181  break;
182  }
183  }
184 
185  // map tiltrotor specific control phases to simple control modes
186  switch (_vtol_schedule.flight_mode) {
187  case vtol_mode::MC_MODE:
189  break;
190 
191  case vtol_mode::FW_MODE:
193  break;
194 
198  break;
199 
202  break;
203  }
204 }
205 
207 {
209 
210  // make sure motors are not tilted
212 }
213 
215 {
217 
218  // make sure motors are tilted forward
220 }
221 
223 {
225 
226  float time_since_trans_start = (float)(hrt_absolute_time() - _vtol_schedule.transition_start) * 1e-6f;
227 
229  // save desired heading for transition and last thrust value
231  }
232 
233  if (_vtol_schedule.flight_mode == vtol_mode::TRANSITION_FRONT_P1) {
234  // for the first part of the transition the rear rotors are enabled
237  }
238 
239  // tilt rotors forward up to certain angle
240  if (_tilt_control <= _params_tiltrotor.tilt_transition) {
241  _tilt_control = _params_tiltrotor.tilt_mc +
242  fabsf(_params_tiltrotor.tilt_transition - _params_tiltrotor.tilt_mc) * time_since_trans_start /
244  }
245 
246 
247  // at low speeds give full weight to MC
248  _mc_roll_weight = 1.0f;
249  _mc_yaw_weight = 1.0f;
250 
251  // reduce MC controls once the plane has picked up speed
254  _mc_yaw_weight = 0.0f;
255  }
256 
261  }
262 
263  // without airspeed do timed weight changes
265  time_since_trans_start > _params->front_trans_time_min) {
266  _mc_roll_weight = 1.0f - (time_since_trans_start - _params->front_trans_time_min) /
269  }
270 
272 
273  } else if (_vtol_schedule.flight_mode == vtol_mode::TRANSITION_FRONT_P2) {
274  // the plane is ready to go into fixed wing mode, tilt the rotors forward completely
275  _tilt_control = _params_tiltrotor.tilt_transition +
276  fabsf(_params_tiltrotor.tilt_fw - _params_tiltrotor.tilt_transition) * time_since_trans_start /
277  _params_tiltrotor.front_trans_dur_p2;
278 
279  _mc_roll_weight = 0.0f;
280  _mc_yaw_weight = 0.0f;
281 
282  // ramp down rear motors (setting MAX_PWM down scales the given output into the new range)
283  int rear_value = (1.0f - time_since_trans_start / _params_tiltrotor.front_trans_dur_p2) *
285 
286 
288 
289 
291 
292  } else if (_vtol_schedule.flight_mode == vtol_mode::TRANSITION_BACK) {
295  }
296 
297 
298  // set idle speed for rotary wing mode
299  if (!flag_idle_mc) {
301  }
302 
303  // tilt rotors back
304  if (_tilt_control > _params_tiltrotor.tilt_mc) {
305  _tilt_control = _params_tiltrotor.tilt_fw -
306  fabsf(_params_tiltrotor.tilt_fw - _params_tiltrotor.tilt_mc) * time_since_trans_start / 1.0f;
307  }
308 
309  _mc_yaw_weight = 1.0f;
310 
311  // while we quickly rotate back the motors keep throttle at idle
312  if (time_since_trans_start < 1.0f) {
313  _mc_throttle_weight = 0.0f;
314  _mc_roll_weight = 0.0f;
315  _mc_pitch_weight = 0.0f;
316 
317  } else {
318  _mc_roll_weight = 1.0f;
319  _mc_pitch_weight = 1.0f;
320  // slowly ramp up throttle to avoid step inputs
321  _mc_throttle_weight = (time_since_trans_start - 1.0f) / 1.0f;
322  }
323  }
324 
328 
329  // copy virtual attitude setpoint to real attitude setpoint (we use multicopter att sp)
331 }
332 
334 {
335  // keep multicopter thrust until we get data from TECS
337 }
338 
339 /**
340 * Write data to actuator output topic.
341 */
343 {
344  // Multirotor output
347 
348  _actuators_out_0->control[actuator_controls_s::INDEX_ROLL] =
349  _actuators_mc_in->control[actuator_controls_s::INDEX_ROLL] * _mc_roll_weight;
350  _actuators_out_0->control[actuator_controls_s::INDEX_PITCH] =
351  _actuators_mc_in->control[actuator_controls_s::INDEX_PITCH] * _mc_pitch_weight;
352  _actuators_out_0->control[actuator_controls_s::INDEX_YAW] =
353  _actuators_mc_in->control[actuator_controls_s::INDEX_YAW] * _mc_yaw_weight;
354 
355  if (_vtol_schedule.flight_mode == vtol_mode::FW_MODE) {
356  _actuators_out_0->control[actuator_controls_s::INDEX_THROTTLE] =
357  _actuators_fw_in->control[actuator_controls_s::INDEX_THROTTLE];
358 
359  /* allow differential thrust if enabled */
360  if (_params->diff_thrust == 1) {
361  _actuators_out_0->control[actuator_controls_s::INDEX_ROLL] =
362  _actuators_fw_in->control[actuator_controls_s::INDEX_YAW] * _params->diff_thrust_scale;
363  }
364 
365  } else {
366  _actuators_out_0->control[actuator_controls_s::INDEX_THROTTLE] =
367  _actuators_mc_in->control[actuator_controls_s::INDEX_THROTTLE] * _mc_throttle_weight;
368  }
369 
370  // Fixed wing output
373 
375 
376  if (_params->elevons_mc_lock && _vtol_schedule.flight_mode == vtol_mode::MC_MODE) {
377  _actuators_out_1->control[actuator_controls_s::INDEX_ROLL] = 0.0f;
378  _actuators_out_1->control[actuator_controls_s::INDEX_PITCH] = 0.0f;
379  _actuators_out_1->control[actuator_controls_s::INDEX_YAW] = 0.0f;
380 
381  } else {
382  _actuators_out_1->control[actuator_controls_s::INDEX_ROLL] =
383  _actuators_fw_in->control[actuator_controls_s::INDEX_ROLL];
384  _actuators_out_1->control[actuator_controls_s::INDEX_PITCH] =
385  _actuators_fw_in->control[actuator_controls_s::INDEX_PITCH];
386  _actuators_out_1->control[actuator_controls_s::INDEX_YAW] =
387  _actuators_fw_in->control[actuator_controls_s::INDEX_YAW];
388  }
389 }
#define PWM_DEFAULT_MAX
Default maximum PWM in us.
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
Definition: Limits.hpp:66
motor_state _motor_state
Definition: vtol_type.h:217
void update_vtol_state() override
Update vtol state.
Definition: tiltrotor.cpp:87
int32_t diff_thrust
Definition: vtol_type.h:71
float _mc_pitch_weight
Definition: vtol_type.h:200
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
Definition: parameters.cpp:589
float _mc_yaw_weight
Definition: vtol_type.h:201
struct Tiltrotor::@143 _params_handles_tiltrotor
float airspeed_blend
Definition: vtol_type.h:66
void update_transition_state() override
Update transition state.
Definition: tiltrotor.cpp:222
struct actuator_controls_s * _actuators_mc_in
Definition: vtol_type.h:186
void update_mc_state() override
Update multicopter state.
Definition: tiltrotor.cpp:206
mode _vtol_mode
Definition: vtol_type.h:174
vtol is in front transition part 1 mode
VtolAttitudeControl * _attc
Definition: vtol_type.h:173
struct Params * _params
Definition: vtol_type.h:194
struct actuator_controls_s * _actuators_out_0
Definition: vtol_type.h:184
struct Tiltrotor::@142 _params_tiltrotor
float diff_thrust_scale
Definition: vtol_type.h:72
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
vtol is in multicopter mode
struct vehicle_attitude_setpoint_s * _v_att_sp
Definition: vtol_type.h:179
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
struct vehicle_attitude_setpoint_s * _mc_virtual_att_sp
Definition: vtol_type.h:180
#define ARSP_YAW_CTRL_DISABLE
Definition: tiltrotor.cpp:45
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
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
void update_fw_state() override
Update fixed wing state.
Definition: tiltrotor.cpp:214
bool flag_idle_mc
Definition: vtol_type.h:196
void fill_actuator_outputs() override
Write data to actuator output topic.
Definition: tiltrotor.cpp:342
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
Definition: parameters.cpp:370
vtol is in front transition part 2 mode
float back_trans_duration
Definition: vtol_type.h:62
Tiltrotor(VtolAttitudeControl *_att_controller)
Definition: tiltrotor.cpp:47
float _thrust_transition
Definition: vtol_type.h:205
float _mc_roll_weight
Definition: vtol_type.h:199
void waiting_on_tecs() override
Special handling opportunity for the time right after transition to FW before TECS is running...
Definition: tiltrotor.cpp:333
float transition_airspeed
Definition: vtol_type.h:63
float _tilt_control
actuator value for the tilt servo
Definition: tiltrotor.h:98
struct Tiltrotor::@144 _vtol_schedule
Specific to tiltrotor with vertical aligned rear engine/s.
float front_trans_time_openloop
Definition: vtol_type.h:59
virtual void update_mc_state()
Update multicopter state.
Definition: vtol_type.cpp:121
struct airspeed_validated_s * _airspeed_validated
Definition: vtol_type.h:190
virtual void update_transition_state()=0
Update transition state.
Definition: vtol_type.cpp:176
bool elevons_mc_lock
Definition: vtol_type.h:54
bool _flag_was_in_trans_mode
Definition: vtol_type.h:210
void parameters_update() override
Definition: tiltrotor.cpp:66
struct actuator_controls_s * _actuators_out_1
Definition: vtol_type.h:185
bool airspeed_disabled
Definition: vtol_type.h:67
vtol is in back transition mode
float front_trans_time_min
Definition: vtol_type.h:60
vtol is in fixed wing mode
#define PWM_DEFAULT_MIN
Default minimum PWM in us.
float front_trans_duration
Definition: vtol_type.h:61
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).