<commit_before>/****************************************************************************
 *
 *   Copyright (c) 2013 Estimation and Control Library (ECL). All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name ECL nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file ecl_wheel_controller.cpp
 * Implementation of a simple PID wheel controller for heading tracking.
 *
 * Authors and acknowledgements in header.
 */

#include "ecl_wheel_controller.h"
#include <stdint.h>
#include <float.h>
#include <geo/geo.h>
#include <ecl/ecl.h>
#include <mathlib/mathlib.h>
#include <systemlib/err.h>
#include <ecl/ecl.h>

ECL_WheelController::ECL_WheelController() :
    ECL_Controller("wheel")
{
}

ECL_WheelController::~ECL_WheelController()
{
}

float ECL_WheelController::control_bodyrate(const struct ECL_ControlData &ctl_data)
{
    /* Do not calculate control signal with bad inputs */
    if (!(PX4_ISFINITE(ctl_data.yaw_rate) &&
          PX4_ISFINITE(ctl_data.groundspeed) &&
          PX4_ISFINITE(ctl_data.groundspeed_scaler))) {
        perf_count(_nonfinite_input_perf);
        return math::constrain(_last_output, -1.0f, 1.0f);
    }

    /* get the usual dt estimate */
    uint64_t dt_micros = ecl_elapsed_time(&_last_run);
    _last_run = ecl_absolute_time();
    float dt = (float)dt_micros * 1e-6f;

    /* lock integral for long intervals */
    bool lock_integrator = ctl_data.lock_integrator;

    if (dt_micros > 500000) {
        lock_integrator = true;
    }

    /* input conditioning */
    float min_speed = 1.0f;

    /* Calculate body angular rate error */
    _rate_error = _rate_setpoint - ctl_data.yaw_rate; //body angular rate error

    if (!lock_integrator && _k_i > 0.0f && ctl_data.groundspeed > min_speed) {

        float id = _rate_error * dt * ctl_data.groundspeed_scaler;

        /*
         * anti-windup: do not allow integrator to increase if actuator is at limit
         */
        if (_last_output < -1.0f) {
            /* only allow motion to center: increase value */
            id = math::max(id, 0.0f);

        } else if (_last_output > 1.0f) {
            /* only allow motion to center: decrease value */
            id = math::min(id, 0.0f);
        }

        _integrator += id;
    }

    /* integrator limit */
    //xxx: until start detection is available: integral part in control signal is limited here
    float integrator_constrained = math::constrain(_integrator * _k_i, -_integrator_max, _integrator_max);

    /* Apply PI rate controller and store non-limited output */
    _last_output = _rate_setpoint * _k_ff * ctl_data.groundspeed_scaler +
            _rate_error * _k_p * ctl_data.groundspeed_scaler * ctl_data.groundspeed_scaler +
            integrator_constrained;
    /*warnx("wheel: _last_output: %.4f, _integrator: %.4f, scaler %.4f",
            (double)_last_output, (double)_integrator, (double)ctl_data.groundspeed_scaler);*/


    return math::constrain(_last_output, -1.0f, 1.0f);
}


float ECL_WheelController::control_attitude(const struct ECL_ControlData &ctl_data)
{
    /* Do not calculate control signal with bad inputs */
    if (!(PX4_ISFINITE(ctl_data.yaw_setpoint) &&
          PX4_ISFINITE(ctl_data.yaw))) {
        perf_count(_nonfinite_input_perf);
        warnx("not controlling wheel");
        return _rate_setpoint;
    }

    /* Calculate the error */
    float yaw_error = ctl_data.yaw_setpoint - ctl_data.yaw;
    /* shortest angle (wrap around) */<commit_msg>Removed spurious print in wheel controller<commit_after>/****************************************************************************
 *
 *   Copyright (c) 2013 Estimation and Control Library (ECL). All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name ECL nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file ecl_wheel_controller.cpp
 * Implementation of a simple PID wheel controller for heading tracking.
 *
 * Authors and acknowledgements in header.
 */

#include "ecl_wheel_controller.h"
#include <stdint.h>
#include <float.h>
#include <geo/geo.h>
#include <ecl/ecl.h>
#include <mathlib/mathlib.h>
#include <systemlib/err.h>
#include <ecl/ecl.h>

ECL_WheelController::ECL_WheelController() :
    ECL_Controller("wheel")
{
}

ECL_WheelController::~ECL_WheelController()
{
}

float ECL_WheelController::control_bodyrate(const struct ECL_ControlData &ctl_data)
{
    /* Do not calculate control signal with bad inputs */
    if (!(PX4_ISFINITE(ctl_data.yaw_rate) &&
          PX4_ISFINITE(ctl_data.groundspeed) &&
          PX4_ISFINITE(ctl_data.groundspeed_scaler))) {
        perf_count(_nonfinite_input_perf);
        return math::constrain(_last_output, -1.0f, 1.0f);
    }

    /* get the usual dt estimate */
    uint64_t dt_micros = ecl_elapsed_time(&_last_run);
    _last_run = ecl_absolute_time();
    float dt = (float)dt_micros * 1e-6f;

    /* lock integral for long intervals */
    bool lock_integrator = ctl_data.lock_integrator;

    if (dt_micros > 500000) {
        lock_integrator = true;
    }

    /* input conditioning */
    float min_speed = 1.0f;

    /* Calculate body angular rate error */
    _rate_error = _rate_setpoint - ctl_data.yaw_rate; //body angular rate error

    if (!lock_integrator && _k_i > 0.0f && ctl_data.groundspeed > min_speed) {

        float id = _rate_error * dt * ctl_data.groundspeed_scaler;

        /*
         * anti-windup: do not allow integrator to increase if actuator is at limit
         */
        if (_last_output < -1.0f) {
            /* only allow motion to center: increase value */
            id = math::max(id, 0.0f);

        } else if (_last_output > 1.0f) {
            /* only allow motion to center: decrease value */
            id = math::min(id, 0.0f);
        }

        _integrator += id;
    }

    /* integrator limit */
    //xxx: until start detection is available: integral part in control signal is limited here
    float integrator_constrained = math::constrain(_integrator * _k_i, -_integrator_max, _integrator_max);

    /* Apply PI rate controller and store non-limited output */
    _last_output = _rate_setpoint * _k_ff * ctl_data.groundspeed_scaler +
            _rate_error * _k_p * ctl_data.groundspeed_scaler * ctl_data.groundspeed_scaler +
            integrator_constrained;
    /*warnx("wheel: _last_output: %.4f, _integrator: %.4f, scaler %.4f",
            (double)_last_output, (double)_integrator, (double)ctl_data.groundspeed_scaler);*/


    return math::constrain(_last_output, -1.0f, 1.0f);
}


float ECL_WheelController::control_attitude(const struct ECL_ControlData &ctl_data)
{
    /* Do not calculate control signal with bad inputs */
    if (!(PX4_ISFINITE(ctl_data.yaw_setpoint) &&
          PX4_ISFINITE(ctl_data.yaw))) {
        perf_count(_nonfinite_input_perf);
        return _rate_setpoint;
    }

    /* Calculate the error */
    float yaw_error = ctl_data.yaw_setpoint - ctl_data.yaw;
    /* shortest angle (wrap around) */
{'fraction_non_alphanumeric': 0.11720245893379018, 'fraction_numerical': 0.009069837750680237, 'mean_word_length': 3.4602247191011237, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7302885', 'n_tokens_mistral': 3073, 'n_tokens_neox': 2855, 'n_words': 932}