2020-07-24 05:29:25 -03:00
|
|
|
#include <AP_Winch/AP_Winch_Backend.h>
|
2022-03-03 23:55:36 -04:00
|
|
|
|
2020-07-24 05:29:25 -03:00
|
|
|
#include <RC_Channel/RC_Channel.h>
|
2022-03-03 23:55:36 -04:00
|
|
|
#include <SRV_Channel/SRV_Channel.h>
|
2020-07-24 05:29:25 -03:00
|
|
|
|
|
|
|
// setup rc input and output
|
2020-08-06 22:23:27 -03:00
|
|
|
void AP_Winch_Backend::init()
|
2020-07-24 05:29:25 -03:00
|
|
|
{
|
|
|
|
// set servo output range
|
|
|
|
SRV_Channels::set_angle(SRV_Channel::k_winch, 1000);
|
|
|
|
|
|
|
|
RC_Channel *rc_input = rc().find_channel_for_option(RC_Channel::AUX_FUNC::WINCH_CONTROL);
|
|
|
|
if (rc_input != nullptr) {
|
|
|
|
// rc input deadzone is required or pilot input will always override autonomous control of winch
|
|
|
|
rc_input->set_default_dead_zone(30);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate the pilot desired rate (+ve deploys line, -ve retracts line, 0 stops) from rc input
|
|
|
|
// may change the state to RATE and update config.rate_desired
|
|
|
|
void AP_Winch_Backend::read_pilot_desired_rate()
|
|
|
|
{
|
|
|
|
// fail if no input channel defined
|
|
|
|
const RC_Channel *rc_input = rc().find_channel_for_option(RC_Channel::AUX_FUNC::WINCH_CONTROL);
|
|
|
|
if (rc_input == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if pilot is controlling winch, set rate to zero during RC failsafe
|
|
|
|
if (!rc().has_valid_input() && (config.control_mode == AP_Winch::ControlMode::RATE_FROM_RC)) {
|
|
|
|
config.rate_desired = 0.0f;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// initialise previous_radio_in
|
|
|
|
if (previous_radio_in == -1) {
|
|
|
|
previous_radio_in = rc_input->get_radio_in();
|
|
|
|
}
|
|
|
|
|
2020-08-06 22:23:27 -03:00
|
|
|
// if significant change in rc input switch to rate mode
|
2020-07-24 05:29:25 -03:00
|
|
|
const int16_t radio_in = rc_input->get_radio_in();
|
|
|
|
if (config.control_mode != AP_Winch::ControlMode::RATE_FROM_RC) {
|
|
|
|
if (abs(radio_in - previous_radio_in) > rc_input->get_dead_zone()) {
|
|
|
|
config.control_mode = AP_Winch::ControlMode::RATE_FROM_RC;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// update desired rate
|
|
|
|
if (config.control_mode == AP_Winch::ControlMode::RATE_FROM_RC) {
|
|
|
|
config.rate_desired = rc_input->norm_input_dz() * config.rate_max;
|
|
|
|
previous_radio_in = radio_in;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// returns the rate limited by the maximum acceleration
|
|
|
|
// this also updates the previous rate so should not be called more than once per loop
|
|
|
|
float AP_Winch_Backend::get_rate_limited_by_accel(float rate, float dt)
|
|
|
|
{
|
|
|
|
// use maximum rate x 2 for maximum acceleration
|
|
|
|
const float rate_change_max = MAX(config.rate_max * 2.0f, 0.1f) * dt;
|
|
|
|
|
|
|
|
// apply acceleration limit
|
|
|
|
const float rate_limited = constrain_float(rate, previous_rate - rate_change_max, previous_rate + rate_change_max);
|
|
|
|
|
|
|
|
// update previous rate for next time
|
|
|
|
set_previous_rate(rate_limited);
|
|
|
|
|
|
|
|
return rate_limited;
|
|
|
|
}
|