robot-rust 0.2.1

The robot-rust project, bindings for wpilib, ctre, and rev in rust.
/*
 * Copyright (C) Cross The Road Electronics.  All rights reserved.
 * License information can be found in CTRE_LICENSE.txt
 * For support and suggestions contact support@ctr-electronics.com or file
 * an issue tracker at https://github.com/CrossTheRoadElec/Phoenix-Releases
 */
#pragma once

#include "ctre/phoenix6/controls/ControlRequest.hpp"
#include <units/frequency.h>
#include <units/time.h>
#include <units/angle.h>
#include <units/angular_velocity.h>
#include <units/current.h>

namespace ctre {
namespace phoenix6 {
namespace controls {

/**
 * Requires Phoenix Pro;
 * Request PID to target position with torque current feedforward.
 * 
 * This control mode will set the motor's position setpoint to the position specified by the user. In
 * addition, it will apply an additional torque current as an arbitrary feedforward value.
 */
class PositionTorqueCurrentFOC final : public ControlRequest {
    ctre::phoenix::StatusCode SendRequest(const char *network, uint32_t deviceHash, std::shared_ptr<ControlRequest> &req) const override;

public:
    /**
     * \brief Position to drive toward in rotations.
     * 
     * - Units: rotations
     * 
     */
    units::angle::turn_t Position;
    /**
     * \brief Velocity to drive toward in rotations per second. This is typically
     * used for motion profiles generated by the robot program.
     * 
     * - Units: rotations per second
     * 
     */
    units::angular_velocity::turns_per_second_t Velocity = 0.0_tps;
    /**
     * \brief Feedforward to apply in torque current in Amperes. This is added to
     * the output of the onboard feedforward terms.
     * 
     * User can use motor's kT to scale Newton-meter to Amperes.
     * 
     * - Units: A
     * 
     */
    units::current::ampere_t FeedForward = 0.0_A;
    /**
     * \brief Select which gains are applied by selecting the slot.  Use the
     * configuration api to set the gain values for the selected slot before
     * enabling this feature. Slot must be within [0,2].
     */
    int Slot = 0;
    /**
     * \brief Set to true to coast the rotor when output is zero (or within
     * deadband).  Set to false to use the NeutralMode configuration setting
     * (default). This flag exists to provide the fundamental behavior of this
     * control when output is zero, which is to provide 0A (zero torque).
     */
    bool OverrideCoastDurNeutral = false;
    /**
     * \brief Set to true to force forward limiting.  This allows users to use other
     * limit switch sensors connected to robot controller.  This also allows use of
     * active sensors that require external power.
     */
    bool LimitForwardMotion = false;
    /**
     * \brief Set to true to force reverse limiting.  This allows users to use other
     * limit switch sensors connected to robot controller.  This also allows use of
     * active sensors that require external power.
     */
    bool LimitReverseMotion = false;
    /**
     * \brief Set to true to ignore hardware limit switches and the
     * LimitForwardMotion and LimitReverseMotion parameters, instead allowing
     * motion.
     * 
     * This can be useful on mechanisms such as an intake/feeder, where a limit
     * switch stops motion while intaking but should be ignored when feeding to a
     * shooter.
     * 
     * The hardware limit faults and Forward/ReverseLimit signals will still report
     * the values of the limit switches regardless of this parameter.
     */
    bool IgnoreHardwareLimits = false;
    /**
     * \brief Set to true to ignore software limits, instead allowing motion.
     * 
     * This can be useful when calibrating the zero point of a mechanism such as an
     * elevator.
     * 
     * The software limit faults will still report the values of the software limits
     * regardless of this parameter.
     */
    bool IgnoreSoftwareLimits = false;
    /**
     * \brief Set to true to delay applying this control request until a timesync
     * boundary (requires Phoenix Pro and CANivore). This eliminates the impact of
     * nondeterministic network delays in exchange for a larger but deterministic
     * control latency.
     * 
     * This requires setting the ControlTimesyncFreqHz config in MotorOutputConfigs.
     * Additionally, when this is enabled, the UpdateFreqHz of this request should
     * be set to 0 Hz.
     */
    bool UseTimesync = false;

    /**
     * \brief The frequency at which this control will update.
     * This is designated in Hertz, with a minimum of 20 Hz
     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
     * Some update frequencies are not supported and will be
     * promoted up to the next highest supported frequency.
     *
     * If this field is set to 0 Hz, the control request will
     * be sent immediately as a one-shot frame. This may be useful
     * for advanced applications that require outputs to be
     * synchronized with data acquisition. In this case, we
     * recommend not exceeding 50 ms between control calls.
     */
    units::frequency::hertz_t UpdateFreqHz{100_Hz};

    /**
     * \brief Requires Phoenix Pro;
     *        Request PID to target position with torque current feedforward.
     * 
     * \details This control mode will set the motor's position setpoint to the
     *          position specified by the user. In addition, it will apply an
     *          additional torque current as an arbitrary feedforward value.
     * 
     * \param Position Position to drive toward in rotations.
     */
    constexpr PositionTorqueCurrentFOC(units::angle::turn_t Position) : ControlRequest{},
        Position{std::move(Position)}
    {}

    constexpr ~PositionTorqueCurrentFOC() override {}

    /**
     * \brief Gets the name of this control request.
     *
     * \returns Name of the control request
     */
    constexpr std::string_view GetName() const override
    {
        return "PositionTorqueCurrentFOC";
    }
    
    /**
     * \brief Modifies this Control Request's Position parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Position to drive toward in rotations.
     * 
     * - Units: rotations
     * 
     *
     * \param newPosition Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithPosition(units::angle::turn_t newPosition)
    {
        Position = std::move(newPosition);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's Velocity parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Velocity to drive toward in rotations per second. This is typically used for
     * motion profiles generated by the robot program.
     * 
     * - Units: rotations per second
     * 
     *
     * \param newVelocity Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithVelocity(units::angular_velocity::turns_per_second_t newVelocity)
    {
        Velocity = std::move(newVelocity);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's FeedForward parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Feedforward to apply in torque current in Amperes. This is added to the
     * output of the onboard feedforward terms.
     * 
     * User can use motor's kT to scale Newton-meter to Amperes.
     * 
     * - Units: A
     * 
     *
     * \param newFeedForward Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithFeedForward(units::current::ampere_t newFeedForward)
    {
        FeedForward = std::move(newFeedForward);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's Slot parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Select which gains are applied by selecting the slot.  Use the configuration
     * api to set the gain values for the selected slot before enabling this
     * feature. Slot must be within [0,2].
     *
     * \param newSlot Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithSlot(int newSlot)
    {
        Slot = std::move(newSlot);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's OverrideCoastDurNeutral parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Set to true to coast the rotor when output is zero (or within deadband).  Set
     * to false to use the NeutralMode configuration setting (default). This flag
     * exists to provide the fundamental behavior of this control when output is
     * zero, which is to provide 0A (zero torque).
     *
     * \param newOverrideCoastDurNeutral Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithOverrideCoastDurNeutral(bool newOverrideCoastDurNeutral)
    {
        OverrideCoastDurNeutral = std::move(newOverrideCoastDurNeutral);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's LimitForwardMotion parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Set to true to force forward limiting.  This allows users to use other limit
     * switch sensors connected to robot controller.  This also allows use of active
     * sensors that require external power.
     *
     * \param newLimitForwardMotion Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithLimitForwardMotion(bool newLimitForwardMotion)
    {
        LimitForwardMotion = std::move(newLimitForwardMotion);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's LimitReverseMotion parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Set to true to force reverse limiting.  This allows users to use other limit
     * switch sensors connected to robot controller.  This also allows use of active
     * sensors that require external power.
     *
     * \param newLimitReverseMotion Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithLimitReverseMotion(bool newLimitReverseMotion)
    {
        LimitReverseMotion = std::move(newLimitReverseMotion);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's IgnoreHardwareLimits parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Set to true to ignore hardware limit switches and the LimitForwardMotion and
     * LimitReverseMotion parameters, instead allowing motion.
     * 
     * This can be useful on mechanisms such as an intake/feeder, where a limit
     * switch stops motion while intaking but should be ignored when feeding to a
     * shooter.
     * 
     * The hardware limit faults and Forward/ReverseLimit signals will still report
     * the values of the limit switches regardless of this parameter.
     *
     * \param newIgnoreHardwareLimits Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithIgnoreHardwareLimits(bool newIgnoreHardwareLimits)
    {
        IgnoreHardwareLimits = std::move(newIgnoreHardwareLimits);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's IgnoreSoftwareLimits parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Set to true to ignore software limits, instead allowing motion.
     * 
     * This can be useful when calibrating the zero point of a mechanism such as an
     * elevator.
     * 
     * The software limit faults will still report the values of the software limits
     * regardless of this parameter.
     *
     * \param newIgnoreSoftwareLimits Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithIgnoreSoftwareLimits(bool newIgnoreSoftwareLimits)
    {
        IgnoreSoftwareLimits = std::move(newIgnoreSoftwareLimits);
        return *this;
    }
    
    /**
     * \brief Modifies this Control Request's UseTimesync parameter and returns itself for
     *        method-chaining and easier to use request API.
     *
     * Set to true to delay applying this control request until a timesync boundary
     * (requires Phoenix Pro and CANivore). This eliminates the impact of
     * nondeterministic network delays in exchange for a larger but deterministic
     * control latency.
     * 
     * This requires setting the ControlTimesyncFreqHz config in MotorOutputConfigs.
     * Additionally, when this is enabled, the UpdateFreqHz of this request should
     * be set to 0 Hz.
     *
     * \param newUseTimesync Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithUseTimesync(bool newUseTimesync)
    {
        UseTimesync = std::move(newUseTimesync);
        return *this;
    }

    /**
     * \brief Sets the frequency at which this control will update.
     * This is designated in Hertz, with a minimum of 20 Hz
     * (every 50 ms) and a maximum of 1000 Hz (every 1 ms).
     * Some update frequencies are not supported and will be
     * promoted up to the next highest supported frequency.
     *
     * If this field is set to 0 Hz, the control request will
     * be sent immediately as a one-shot frame. This may be useful
     * for advanced applications that require outputs to be
     * synchronized with data acquisition. In this case, we
     * recommend not exceeding 50 ms between control calls.
     *
     * \param newUpdateFreqHz Parameter to modify
     * \returns Itself
     */
    constexpr PositionTorqueCurrentFOC &WithUpdateFreqHz(units::frequency::hertz_t newUpdateFreqHz)
    {
        UpdateFreqHz = newUpdateFreqHz;
        return *this;
    }

    /**
     * \brief Returns a string representation of the object.
     *
     * \returns a string representation of the object.
     */
    std::string ToString() const override;

    /**
     * \brief Gets information about this control request.
     *
     * \returns Map of control parameter names and corresponding applied values
     */
    std::map<std::string, std::string> GetControlInfo() const override;
};

}
}
}