123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- #include <AP_HAL/AP_HAL.h>
- #include <AP_Math/AP_Math.h>
- #include <GCS_MAVLink/GCS.h>
- #include "AP_MotorsTri.h"
- extern const AP_HAL::HAL& hal;
- void AP_MotorsTri::init(motor_frame_class frame_class, motor_frame_type frame_type)
- {
- add_motor_num(AP_MOTORS_MOT_1);
- add_motor_num(AP_MOTORS_MOT_2);
- add_motor_num(AP_MOTORS_MOT_4);
-
- set_update_rate(_speed_hz);
-
- motor_enabled[AP_MOTORS_MOT_1] = true;
- motor_enabled[AP_MOTORS_MOT_2] = true;
- motor_enabled[AP_MOTORS_MOT_4] = true;
-
- _yaw_servo = SRV_Channels::get_channel_for(SRV_Channel::k_motor7, AP_MOTORS_CH_TRI_YAW);
- if (!_yaw_servo) {
- gcs().send_text(MAV_SEVERITY_ERROR, "MotorsTri: unable to setup yaw channel");
-
- return;
- }
-
- add_motor_num(AP_MOTORS_CH_TRI_YAW);
-
- _flags.initialised_ok = (frame_class == MOTOR_FRAME_TRI);
- }
- void AP_MotorsTri::set_frame_class_and_type(motor_frame_class frame_class, motor_frame_type frame_type)
- {
- _flags.initialised_ok = (frame_class == MOTOR_FRAME_TRI);
- }
- void AP_MotorsTri::set_update_rate(uint16_t speed_hz)
- {
-
- _speed_hz = speed_hz;
-
- uint32_t mask =
- 1U << AP_MOTORS_MOT_1 |
- 1U << AP_MOTORS_MOT_2 |
- 1U << AP_MOTORS_MOT_4;
- rc_set_freq(mask, _speed_hz);
- }
- void AP_MotorsTri::output_to_motors()
- {
- switch (_spool_state) {
- case SpoolState::SHUT_DOWN:
-
- rc_write(AP_MOTORS_MOT_1, output_to_pwm(0));
- rc_write(AP_MOTORS_MOT_2, output_to_pwm(0));
- rc_write(AP_MOTORS_MOT_4, output_to_pwm(0));
- rc_write(AP_MOTORS_CH_TRI_YAW, _yaw_servo->get_trim());
- break;
- case SpoolState::GROUND_IDLE:
-
- set_actuator_with_slew(_actuator[1], actuator_spin_up_to_ground_idle());
- set_actuator_with_slew(_actuator[2], actuator_spin_up_to_ground_idle());
- set_actuator_with_slew(_actuator[4], actuator_spin_up_to_ground_idle());
- rc_write(AP_MOTORS_MOT_1, output_to_pwm(_actuator[1]));
- rc_write(AP_MOTORS_MOT_2, output_to_pwm(_actuator[2]));
- rc_write(AP_MOTORS_MOT_4, output_to_pwm(_actuator[4]));
- rc_write(AP_MOTORS_CH_TRI_YAW, _yaw_servo->get_trim());
- break;
- case SpoolState::SPOOLING_UP:
- case SpoolState::THROTTLE_UNLIMITED:
- case SpoolState::SPOOLING_DOWN:
-
- set_actuator_with_slew(_actuator[1], thrust_to_actuator(_thrust_right));
- set_actuator_with_slew(_actuator[2], thrust_to_actuator(_thrust_left));
- set_actuator_with_slew(_actuator[4], thrust_to_actuator(_thrust_rear));
- rc_write(AP_MOTORS_MOT_1, output_to_pwm(_actuator[1]));
- rc_write(AP_MOTORS_MOT_2, output_to_pwm(_actuator[2]));
- rc_write(AP_MOTORS_MOT_4, output_to_pwm(_actuator[4]));
- rc_write(AP_MOTORS_CH_TRI_YAW, calc_yaw_radio_output(_pivot_angle, radians(_yaw_servo_angle_max_deg)));
- break;
- }
- }
- uint16_t AP_MotorsTri::get_motor_mask()
- {
-
- uint16_t motor_mask = (1U << AP_MOTORS_MOT_1) |
- (1U << AP_MOTORS_MOT_2) |
- (1U << AP_MOTORS_MOT_4) |
- (1U << AP_MOTORS_CH_TRI_YAW);
- uint16_t mask = rc_map_mask(motor_mask);
-
- mask |= AP_MotorsMulticopter::get_motor_mask();
- return mask;
- }
- void AP_MotorsTri::output_armed_stabilizing()
- {
- float roll_thrust;
- float pitch_thrust;
- float yaw_thrust;
- float throttle_thrust;
- float throttle_avg_max;
- float throttle_thrust_best_rpy;
- float rpy_scale = 1.0f;
- float rpy_low = 0.0f;
- float rpy_high = 0.0f;
- float thr_adj;
-
- _yaw_servo_angle_max_deg = constrain_float(_yaw_servo_angle_max_deg, AP_MOTORS_TRI_SERVO_RANGE_DEG_MIN, AP_MOTORS_TRI_SERVO_RANGE_DEG_MAX);
-
- const float compensation_gain = get_compensation_gain();
- roll_thrust = (_roll_in + _roll_in_ff) * compensation_gain;
- pitch_thrust = (_pitch_in + _pitch_in_ff) * compensation_gain;
- yaw_thrust = (_yaw_in + _yaw_in_ff) * compensation_gain * sinf(radians(_yaw_servo_angle_max_deg));
- throttle_thrust = get_throttle() * compensation_gain;
- throttle_avg_max = _throttle_avg_max * compensation_gain;
-
- _pivot_angle = safe_asin(yaw_thrust);
- if (fabsf(_pivot_angle) > radians(_yaw_servo_angle_max_deg)) {
- limit.yaw = true;
- _pivot_angle = constrain_float(_pivot_angle, -radians(_yaw_servo_angle_max_deg), radians(_yaw_servo_angle_max_deg));
- }
- float pivot_thrust_max = cosf(_pivot_angle);
- float thrust_max = 1.0f;
-
- if (throttle_thrust <= 0.0f) {
- throttle_thrust = 0.0f;
- limit.throttle_lower = true;
- }
- if (throttle_thrust >= _throttle_thrust_max) {
- throttle_thrust = _throttle_thrust_max;
- limit.throttle_upper = true;
- }
- throttle_avg_max = constrain_float(throttle_avg_max, throttle_thrust, _throttle_thrust_max);
-
-
-
-
- _thrust_right = roll_thrust * -0.5f + pitch_thrust * 0.5f;
- _thrust_left = roll_thrust * 0.5f + pitch_thrust * 0.5f;
- _thrust_rear = pitch_thrust * -0.5f;
-
-
-
- rpy_low = MIN(_thrust_right, _thrust_left);
- rpy_high = MAX(_thrust_right, _thrust_left);
- if (rpy_low > _thrust_rear) {
- rpy_low = _thrust_rear;
- }
-
- if ((1.0f - rpy_high) > (pivot_thrust_max - _thrust_rear)) {
- thrust_max = pivot_thrust_max;
- rpy_high = _thrust_rear;
- }
-
-
-
-
-
-
-
-
-
-
- throttle_thrust_best_rpy = MIN(0.5f * thrust_max - (rpy_low + rpy_high) / 2.0, throttle_avg_max);
- if (is_zero(rpy_low)) {
- rpy_scale = 1.0f;
- } else {
- rpy_scale = constrain_float(-throttle_thrust_best_rpy / rpy_low, 0.0f, 1.0f);
- }
-
- thr_adj = throttle_thrust - throttle_thrust_best_rpy;
- if (rpy_scale < 1.0f) {
-
- limit.roll = true;
- limit.pitch = true;
- if (thr_adj > 0.0f) {
- limit.throttle_upper = true;
- }
- thr_adj = 0.0f;
- } else {
- if (thr_adj < -(throttle_thrust_best_rpy + rpy_low)) {
-
- thr_adj = -(throttle_thrust_best_rpy + rpy_low);
- } else if (thr_adj > thrust_max - (throttle_thrust_best_rpy + rpy_high)) {
-
- thr_adj = thrust_max - (throttle_thrust_best_rpy + rpy_high);
- limit.throttle_upper = true;
- }
- }
-
- _thrust_right = throttle_thrust_best_rpy + thr_adj + rpy_scale * _thrust_right;
- _thrust_left = throttle_thrust_best_rpy + thr_adj + rpy_scale * _thrust_left;
- _thrust_rear = throttle_thrust_best_rpy + thr_adj + rpy_scale * _thrust_rear;
-
-
- _thrust_rear = _thrust_rear / cosf(_pivot_angle);
-
-
- _thrust_right = constrain_float(_thrust_right, 0.0f, 1.0f);
- _thrust_left = constrain_float(_thrust_left, 0.0f, 1.0f);
- _thrust_rear = constrain_float(_thrust_rear, 0.0f, 1.0f);
- }
- void AP_MotorsTri::output_test_seq(uint8_t motor_seq, int16_t pwm)
- {
-
- if (!armed()) {
- return;
- }
-
- switch (motor_seq) {
- case 1:
-
- rc_write(AP_MOTORS_MOT_1, pwm);
- break;
- case 2:
-
- rc_write(AP_MOTORS_MOT_4, pwm);
- break;
- case 3:
-
- rc_write(AP_MOTORS_CH_TRI_YAW, pwm);
- break;
- case 4:
-
- rc_write(AP_MOTORS_MOT_2, pwm);
- break;
- default:
-
- break;
- }
- }
- int16_t AP_MotorsTri::calc_yaw_radio_output(float yaw_input, float yaw_input_max)
- {
- int16_t ret;
- if (_yaw_servo->get_reversed()) {
- yaw_input = -yaw_input;
- }
- if (yaw_input >= 0) {
- ret = (_yaw_servo->get_trim() + (yaw_input / yaw_input_max * (_yaw_servo->get_output_max() - _yaw_servo->get_trim())));
- } else {
- ret = (_yaw_servo->get_trim() + (yaw_input / yaw_input_max * (_yaw_servo->get_trim() - _yaw_servo->get_output_min())));
- }
- return ret;
- }
- void AP_MotorsTri::thrust_compensation(void)
- {
- if (_thrust_compensation_callback) {
-
- float thrust[4] { _thrust_right, _thrust_left, 0, _thrust_rear };
-
- _thrust_compensation_callback(thrust, 4);
-
- _thrust_right = thrust[0];
- _thrust_left = thrust[1];
- _thrust_rear = thrust[3];
- }
- }
- void AP_MotorsTri::output_motor_mask(float thrust, uint8_t mask, float rudder_dt)
- {
-
- AP_MotorsMulticopter::output_motor_mask(thrust, mask, rudder_dt);
-
- rc_write(AP_MOTORS_CH_TRI_YAW, _yaw_servo->get_trim());
- }
- float AP_MotorsTri::get_roll_factor(uint8_t i)
- {
- float ret = 0.0f;
- switch (i) {
-
- case AP_MOTORS_MOT_1:
- ret = -1.0f;
- break;
-
- case AP_MOTORS_MOT_2:
- ret = 1.0f;
- break;
- }
- return ret;
- }
|