/* * 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 . */ #include #include #include #include "AP_MotorsHeli_Quad.h" extern const AP_HAL::HAL& hal; const AP_Param::GroupInfo AP_MotorsHeli_Quad::var_info[] = { AP_NESTEDGROUPINFO(AP_MotorsHeli, 0), // Indices 1-3 were used by RSC_PWM_MIN, RSC_PWM_MAX and RSC_PWM_REV and should not be used AP_GROUPEND }; #define QUAD_SERVO_MAX_ANGLE 4500 // set update rate to motors - a value in hertz void AP_MotorsHeli_Quad::set_update_rate( uint16_t speed_hz ) { // record requested speed _speed_hz = speed_hz; // setup fast channels uint32_t mask = 0; for (uint8_t i=0; i= _collective_max ) { _collective_min = AP_MOTORS_HELI_COLLECTIVE_MIN; _collective_max = AP_MOTORS_HELI_COLLECTIVE_MAX; } _collective_mid = constrain_int16(_collective_mid, _collective_min, _collective_max); // calculate collective mid point as a number from 0 to 1000 _collective_mid_pct = ((float)(_collective_mid-_collective_min))/((float)(_collective_max-_collective_min)); // calculate factors based on swash type and servo position calculate_roll_pitch_collective_factors(); // set mode of main rotor controller and trigger recalculation of scalars _main_rotor.set_control_mode(static_cast(_main_rotor._rsc_mode.get())); calculate_armed_scalars(); } // calculate_swash_factors - calculate factors based on swash type and servo position void AP_MotorsHeli_Quad::calculate_roll_pitch_collective_factors() { // assume X quad layout, with motors at 45, 135, 225 and 315 degrees // order FrontRight, RearLeft, FrontLeft, RearLeft const float angles[AP_MOTORS_HELI_QUAD_NUM_MOTORS] = { 45, 225, 315, 135 }; const bool x_clockwise[AP_MOTORS_HELI_QUAD_NUM_MOTORS] = { false, false, true, true }; const float cos45 = cosf(radians(45)); for (uint8_t i=0; i= 1.0f) { collective_out = 1.0f; limit.throttle_upper = true; } // ensure not below landed/landing collective if (_heliflags.landing_collective && collective_out < _collective_mid_pct) { collective_out = _collective_mid_pct; limit.throttle_lower = true; } float collective_range = (_collective_max - _collective_min) * 0.001f; if (_heliflags.inverted_flight) { collective_out = 1.0f - collective_out; } // feed power estimate into main rotor controller _main_rotor.set_collective(fabsf(collective_out)); // rescale collective for overhead calc collective_out -= _collective_mid_pct; // reserve some collective for attitude control collective_out *= collective_range; for (uint8_t i=0; i