// init void AP_MotorsHeli::Init() { // set update rate set_update_rate(_speed_hz); // ensure inputs are not passed through to servos _servo_manual = 0; // initialise some scalers recalc_scalers(); // initialise swash plate init_swash(); }
// init void AP_MotorsHeli::Init() { // set update rate set_update_rate(_speed_hz); // ensure inputs are not passed through to servos _servo_manual = 0; // initialise some scalers recalc_scalers(); // initialise swash plate init_swash(); // disable channels 7 and 8 from being used by RC_Channel_aux RC_Channel_aux::disable_aux_channel(_motor_to_channel_map[AP_MOTORS_HELI_AUX]); RC_Channel_aux::disable_aux_channel(_motor_to_channel_map[AP_MOTORS_HELI_RSC]); }
// // heli_move_swash - moves swash plate to attitude of parameters passed in // - expected ranges: // roll : -4500 ~ 4500 // pitch: -4500 ~ 4500 // collective: 0 ~ 1000 // yaw: -4500 ~ 4500 // void AP_MotorsHeli::move_swash(int16_t roll_out, int16_t pitch_out, int16_t coll_in, int16_t yaw_out) { int16_t yaw_offset = 0; int16_t coll_out_scaled; if( servo_manual == 1 ) { // are we in manual servo mode? (i.e. swash set-up mode)? // check if we need to free up the swash if( _swash_initialised ) { reset_swash(); } coll_out_scaled = coll_in * _collective_scalar + _rc_throttle->radio_min - 1000; }else{ // regular flight mode // check if we need to reinitialise the swash if( !_swash_initialised ) { init_swash(); } // rescale roll_out and pitch-out into the min and max ranges to provide linear motion // across the input range instead of stopping when the input hits the constrain value // these calculations are based on an assumption of the user specified roll_max and pitch_max // coming into this equation at 4500 or less, and based on the original assumption of the // total _servo_x.servo_out range being -4500 to 4500. roll_out = roll_out * _roll_scaler; roll_out = constrain_int16(roll_out, (int16_t)-roll_max, (int16_t)roll_max); pitch_out = pitch_out * _pitch_scaler; pitch_out = constrain_int16(pitch_out, (int16_t)-pitch_max, (int16_t)pitch_max); // scale collective pitch coll_out = constrain_int16(coll_in, 0, 1000); if (stab_throttle){ coll_out = coll_out * _stab_throttle_scalar + stab_col_min*10; } coll_out_scaled = coll_out * _collective_scalar + collective_min - 1000; // rudder feed forward based on collective if( !ext_gyro_enabled ) { yaw_offset = collective_yaw_effect * abs(coll_out_scaled - throttle_mid); } } // swashplate servos _servo_1->servo_out = (_rollFactor[CH_1] * roll_out + _pitchFactor[CH_1] * pitch_out)/10 + _collectiveFactor[CH_1] * coll_out_scaled + (_servo_1->radio_trim-1500); _servo_2->servo_out = (_rollFactor[CH_2] * roll_out + _pitchFactor[CH_2] * pitch_out)/10 + _collectiveFactor[CH_2] * coll_out_scaled + (_servo_2->radio_trim-1500); if( swash_type == AP_MOTORS_HELI_SWASH_H1 ) { _servo_1->servo_out += 500; _servo_2->servo_out += 500; } _servo_3->servo_out = (_rollFactor[CH_3] * roll_out + _pitchFactor[CH_3] * pitch_out)/10 + _collectiveFactor[CH_3] * coll_out_scaled + (_servo_3->radio_trim-1500); _servo_4->servo_out = yaw_out + yaw_offset; // use servo_out to calculate pwm_out and radio_out _servo_1->calc_pwm(); _servo_2->calc_pwm(); _servo_3->calc_pwm(); _servo_4->calc_pwm(); // actually move the servos hal.rcout->write(_motor_to_channel_map[AP_MOTORS_MOT_1], _servo_1->radio_out); hal.rcout->write(_motor_to_channel_map[AP_MOTORS_MOT_2], _servo_2->radio_out); hal.rcout->write(_motor_to_channel_map[AP_MOTORS_MOT_3], _servo_3->radio_out); hal.rcout->write(_motor_to_channel_map[AP_MOTORS_MOT_4], _servo_4->radio_out); // to be compatible with other frame types motor_out[AP_MOTORS_MOT_1] = _servo_1->radio_out; motor_out[AP_MOTORS_MOT_2] = _servo_2->radio_out; motor_out[AP_MOTORS_MOT_3] = _servo_3->radio_out; motor_out[AP_MOTORS_MOT_4] = _servo_4->radio_out; // output gyro value if( ext_gyro_enabled ) { hal.rcout->write(AP_MOTORS_HELI_EXT_GYRO, ext_gyro_gain); } }
// // heli_move_swash - moves swash plate to attitude of parameters passed in // - expected ranges: // roll : -4500 ~ 4500 // pitch: -4500 ~ 4500 // collective: 0 ~ 1000 // yaw: -4500 ~ 4500 // void AP_MotorsHeli::move_swash(int16_t roll_out, int16_t pitch_out, int16_t coll_in, int16_t yaw_out) { int16_t yaw_offset = 0; int16_t coll_out_scaled; // initialize limits flag limit.roll_pitch = false; limit.yaw = false; limit.throttle_lower = false; limit.throttle_upper = false; if (_servo_manual == 1) { // are we in manual servo mode? (i.e. swash set-up mode)? // check if we need to free up the swash if (_heliflags.swash_initialised) { reset_swash(); } // To-Do: This equation seems to be wrong. It probably restricts swash movement so that swash setup doesn't work right. // _collective_scalar should probably not be used or set to 1? coll_out_scaled = coll_in * _collective_scalar + _throttle_radio_min - 1000; }else{ // regular flight mode // check if we need to reinitialise the swash if (!_heliflags.swash_initialised) { init_swash(); } // rescale roll_out and pitch-out into the min and max ranges to provide linear motion // across the input range instead of stopping when the input hits the constrain value // these calculations are based on an assumption of the user specified roll_max and pitch_max // coming into this equation at 4500 or less, and based on the original assumption of the // total _servo_x.servo_out range being -4500 to 4500. roll_out = roll_out * _roll_scaler; if (roll_out < -_roll_max) { roll_out = -_roll_max; limit.roll_pitch = true; } if (roll_out > _roll_max) { roll_out = _roll_max; limit.roll_pitch = true; } // scale pitch and update limits pitch_out = pitch_out * _pitch_scaler; if (pitch_out < -_pitch_max) { pitch_out = -_pitch_max; limit.roll_pitch = true; } if (pitch_out > _pitch_max) { pitch_out = _pitch_max; limit.roll_pitch = true; } // constrain collective input _collective_out = coll_in; if (_collective_out <= 0) { _collective_out = 0; limit.throttle_lower = true; } if (_collective_out >= 1000) { _collective_out = 1000; limit.throttle_upper = true; } // ensure not below landed/landing collective if (_heliflags.landing_collective && _collective_out < _land_collective_min) { _collective_out = _land_collective_min; limit.throttle_lower = true; } // scale collective pitch coll_out_scaled = _collective_out * _collective_scalar + _collective_min - 1000; // rudder feed forward based on collective // the feed-forward is not required when the motor is shut down and not creating torque // also not required if we are using external gyro if ((_desired_rotor_speed > 0) && _tail_type != AP_MOTORS_HELI_TAILTYPE_SERVO_EXTGYRO) { // sanity check collective_yaw_effect _collective_yaw_effect = constrain_float(_collective_yaw_effect, -AP_MOTOR_HELI_COLYAW_RANGE, AP_MOTOR_HELI_COLYAW_RANGE); yaw_offset = _collective_yaw_effect * abs(_collective_out - _collective_mid_pwm); } } // swashplate servos _servo_1.servo_out = (_rollFactor[CH_1] * roll_out + _pitchFactor[CH_1] * pitch_out)/10 + _collectiveFactor[CH_1] * coll_out_scaled + (_servo_1.radio_trim-1500); _servo_2.servo_out = (_rollFactor[CH_2] * roll_out + _pitchFactor[CH_2] * pitch_out)/10 + _collectiveFactor[CH_2] * coll_out_scaled + (_servo_2.radio_trim-1500); if (_swash_type == AP_MOTORS_HELI_SWASH_H1) { _servo_1.servo_out += 500; _servo_2.servo_out += 500; } _servo_3.servo_out = (_rollFactor[CH_3] * roll_out + _pitchFactor[CH_3] * pitch_out)/10 + _collectiveFactor[CH_3] * coll_out_scaled + (_servo_3.radio_trim-1500); _servo_4.servo_out = yaw_out + yaw_offset; // constrain yaw and update limits if (_servo_4.servo_out < -4500) { _servo_4.servo_out = -4500; limit.yaw = true; } if (_servo_4.servo_out > 4500) { _servo_4.servo_out = 4500; limit.yaw = true; } // use servo_out to calculate pwm_out and radio_out _servo_1.calc_pwm(); _servo_2.calc_pwm(); _servo_3.calc_pwm(); _servo_4.calc_pwm(); // actually move the servos hal.rcout->write(pgm_read_byte(&_motor_to_channel_map[AP_MOTORS_MOT_1]), _servo_1.radio_out); hal.rcout->write(pgm_read_byte(&_motor_to_channel_map[AP_MOTORS_MOT_2]), _servo_2.radio_out); hal.rcout->write(pgm_read_byte(&_motor_to_channel_map[AP_MOTORS_MOT_3]), _servo_3.radio_out); hal.rcout->write(pgm_read_byte(&_motor_to_channel_map[AP_MOTORS_MOT_4]), _servo_4.radio_out); // output gain to exernal gyro if (_tail_type == AP_MOTORS_HELI_TAILTYPE_SERVO_EXTGYRO) { write_aux(_ext_gyro_gain); } }
// // heli_move_swash - moves swash plate to attitude of parameters passed in // - expected ranges: // roll : -4500 ~ 4500 // pitch: -4500 ~ 4500 // collective: 0 ~ 1000 // yaw: -4500 ~ 4500 // void AP_MotorsHeli::move_swash(int16_t roll_out, int16_t pitch_out, int16_t coll_in, int16_t yaw_out) { int16_t yaw_offset = 0; int16_t coll_out_scaled; // initialize limits flag limit.roll_pitch = false; limit.yaw = false; limit.throttle_lower = false; limit.throttle_upper = false; if (_servo_manual == 1) { // are we in manual servo mode? (i.e. swash set-up mode)? // check if we need to free up the swash if (_heliflags.swash_initialised) { reset_swash(); } coll_out_scaled = coll_in * _collective_scalar + _rc_throttle->radio_min - 1000; }else{ // regular flight mode // check if we need to reinitialise the swash if (!_heliflags.swash_initialised) { init_swash(); } // rescale roll_out and pitch-out into the min and max ranges to provide linear motion // across the input range instead of stopping when the input hits the constrain value // these calculations are based on an assumption of the user specified roll_max and pitch_max // coming into this equation at 4500 or less, and based on the original assumption of the // total _servo_x.servo_out range being -4500 to 4500. roll_out = roll_out * _roll_scaler; if (roll_out < -_roll_max) { roll_out = -_roll_max; limit.roll_pitch = true; } if (roll_out > _roll_max) { roll_out = _roll_max; limit.roll_pitch = true; } // scale pitch and update limits pitch_out = pitch_out * _pitch_scaler; if (pitch_out < -_pitch_max) { pitch_out = -_pitch_max; limit.roll_pitch = true; } if (pitch_out > _pitch_max) { pitch_out = _pitch_max; limit.roll_pitch = true; } // constrain collective input _collective_out = coll_in; if (_collective_out <= 0) { _collective_out = 0; limit.throttle_lower = true; } if (_collective_out >= 1000) { _collective_out = 1000; limit.throttle_upper = true; } // ensure not below landed/landing collective if (_heliflags.landing_collective && _collective_out < _land_collective_min) { _collective_out = _land_collective_min; limit.throttle_lower = true; } // scale collective pitch coll_out_scaled = _collective_out * _collective_scalar + _collective_min - 1000; // rudder feed forward based on collective // the feed-forward is not required when the motor is shut down and not creating torque // also not required if we are using external gyro if (motor_runup_complete() && _tail_type != AP_MOTORS_HELI_TAILTYPE_SERVO_EXTGYRO) { yaw_offset = _collective_yaw_effect * abs(_collective_out - _collective_mid_pwm); } } // swashplate servos _servo_1->servo_out = (_rollFactor[CH_1] * roll_out + _pitchFactor[CH_1] * pitch_out)/10 + _collectiveFactor[CH_1] * coll_out_scaled + (_servo_1->radio_trim-1500); _servo_2->servo_out = (_rollFactor[CH_2] * roll_out + _pitchFactor[CH_2] * pitch_out)/10 + _collectiveFactor[CH_2] * coll_out_scaled + (_servo_2->radio_trim-1500); if (_swash_type == AP_MOTORS_HELI_SWASH_H1) { _servo_1->servo_out += 500; _servo_2->servo_out += 500; } _servo_3->servo_out = (_rollFactor[CH_3] * roll_out + _pitchFactor[CH_3] * pitch_out)/10 + _collectiveFactor[CH_3] * coll_out_scaled + (_servo_3->radio_trim-1500); _servo_4->servo_out = yaw_out + yaw_offset; // constrain yaw and update limits if (_servo_4->servo_out < -4500) { _servo_4->servo_out = -4500; limit.yaw = true; } if (_servo_4->servo_out > 4500) { _servo_4->servo_out = 4500; limit.yaw = true; } // use servo_out to calculate pwm_out and radio_out _servo_1->calc_pwm(); _servo_2->calc_pwm(); _servo_3->calc_pwm(); _servo_4->calc_pwm(); // actually move the servos hal.rcout->write(_motor_to_channel_map[AP_MOTORS_MOT_1], _servo_1->radio_out); hal.rcout->write(_motor_to_channel_map[AP_MOTORS_MOT_2], _servo_2->radio_out); hal.rcout->write(_motor_to_channel_map[AP_MOTORS_MOT_3], _servo_3->radio_out); hal.rcout->write(_motor_to_channel_map[AP_MOTORS_MOT_4], _servo_4->radio_out); // output gain to exernal gyro if (_tail_type == AP_MOTORS_HELI_TAILTYPE_SERVO_EXTGYRO) { write_aux(_ext_gyro_gain); } // to be compatible with other frame types motor_out[AP_MOTORS_MOT_1] = _servo_1->radio_out; motor_out[AP_MOTORS_MOT_2] = _servo_2->radio_out; motor_out[AP_MOTORS_MOT_3] = _servo_3->radio_out; motor_out[AP_MOTORS_MOT_4] = _servo_4->radio_out; }