You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
4.1 KiB
121 lines
4.1 KiB
/* |
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
*/ |
|
|
|
/* |
|
* AP_MotorsTailsitter.cpp - ArduCopter motors library for tailsitters |
|
* |
|
*/ |
|
|
|
#include <AP_HAL/AP_HAL.h> |
|
#include <AP_Math/AP_Math.h> |
|
#include "AP_MotorsTailsitter.h" |
|
#include <GCS_MAVLink/GCS.h> |
|
|
|
extern const AP_HAL::HAL& hal; |
|
|
|
#define SERVO_OUTPUT_RANGE 4500 |
|
#define THROTTLE_RANGE 100 |
|
|
|
// init |
|
void AP_MotorsTailsitter::init(motor_frame_class frame_class, motor_frame_type frame_type) |
|
{ |
|
// record successful initialisation if what we setup was the desired frame_class |
|
_flags.initialised_ok = (frame_class == MOTOR_FRAME_TAILSITTER); |
|
} |
|
|
|
|
|
/// Constructor |
|
AP_MotorsTailsitter::AP_MotorsTailsitter(uint16_t loop_rate, uint16_t speed_hz) : |
|
AP_MotorsMulticopter(loop_rate, speed_hz) |
|
{ |
|
SRV_Channels::set_rc_frequency(SRV_Channel::k_throttleLeft, speed_hz); |
|
SRV_Channels::set_rc_frequency(SRV_Channel::k_throttleRight, speed_hz); |
|
} |
|
|
|
void AP_MotorsTailsitter::output_to_motors() |
|
{ |
|
if (!_flags.initialised_ok) { |
|
return; |
|
} |
|
float throttle_left = 0; |
|
float throttle_right = 0; |
|
|
|
switch (_spool_mode) { |
|
case SHUT_DOWN: |
|
_throttle = 0; |
|
// set limits flags |
|
limit.roll_pitch = true; |
|
limit.yaw = true; |
|
limit.throttle_lower = true; |
|
limit.throttle_upper = true; |
|
break; |
|
case SPIN_WHEN_ARMED: |
|
// sends output to motors when armed but not flying |
|
_throttle = constrain_float(_spin_up_ratio, 0.0f, 1.0f) * _spin_min; |
|
// set limits flags |
|
limit.roll_pitch = true; |
|
limit.yaw = true; |
|
limit.throttle_lower = true; |
|
limit.throttle_upper = true; |
|
break; |
|
case SPOOL_UP: |
|
case THROTTLE_UNLIMITED: |
|
case SPOOL_DOWN: |
|
throttle_left = constrain_float(_throttle + _rudder*0.5, 0, 1); |
|
throttle_right = constrain_float(_throttle - _rudder*0.5, 0, 1); |
|
// initialize limits flags |
|
limit.roll_pitch = false; |
|
limit.yaw = false; |
|
limit.throttle_lower = false; |
|
limit.throttle_upper = false; |
|
break; |
|
} |
|
// outputs are setup here, and written to the HAL by the plane servos loop |
|
SRV_Channels::set_output_scaled(SRV_Channel::k_aileron, _aileron*SERVO_OUTPUT_RANGE); |
|
SRV_Channels::set_output_scaled(SRV_Channel::k_elevator, _elevator*SERVO_OUTPUT_RANGE); |
|
SRV_Channels::set_output_scaled(SRV_Channel::k_rudder, _rudder*SERVO_OUTPUT_RANGE); |
|
SRV_Channels::set_output_scaled(SRV_Channel::k_throttle, _throttle*THROTTLE_RANGE); |
|
|
|
// also support differential roll with twin motors |
|
SRV_Channels::set_output_scaled(SRV_Channel::k_throttleLeft, throttle_left*THROTTLE_RANGE); |
|
SRV_Channels::set_output_scaled(SRV_Channel::k_throttleRight, throttle_right*THROTTLE_RANGE); |
|
|
|
#if APM_BUILD_TYPE(APM_BUILD_ArduCopter) |
|
SRV_Channels::calc_pwm(); |
|
SRV_Channels::output_ch_all(); |
|
#endif |
|
} |
|
|
|
// calculate outputs to the motors |
|
void AP_MotorsTailsitter::output_armed_stabilizing() |
|
{ |
|
_aileron = -_yaw_in; |
|
_elevator = _pitch_in; |
|
_rudder = _roll_in; |
|
_throttle = get_throttle(); |
|
|
|
// sanity check throttle is above zero and below current limited throttle |
|
if (_throttle <= 0.0f) { |
|
_throttle = 0.0f; |
|
limit.throttle_lower = true; |
|
} |
|
if (_throttle >= _throttle_thrust_max) { |
|
_throttle = _throttle_thrust_max; |
|
limit.throttle_upper = true; |
|
} |
|
|
|
_throttle = constrain_float(_throttle, 0.1, 1); |
|
} |
|
|
|
|