diff --git a/include/api.h b/include/api.h index fab9a61bc..69c918678 100644 --- a/include/api.h +++ b/include/api.h @@ -55,26 +55,27 @@ #include "pros/misc.h" #include "pros/motors.h" #include "pros/optical.h" -#include "pros/rtos.h" #include "pros/rotation.h" +#include "pros/rtos.h" #include "pros/screen.h" #include "pros/vision.h" #ifdef __cplusplus #include "pros/adi.hpp" #include "pros/colors.hpp" +#include "pros/device.hpp" #include "pros/distance.hpp" #include "pros/gps.hpp" #include "pros/imu.hpp" +#include "pros/link.hpp" #include "pros/misc.hpp" +#include "pros/motor_group.hpp" #include "pros/motors.hpp" #include "pros/optical.hpp" #include "pros/rotation.hpp" #include "pros/rtos.hpp" #include "pros/screen.hpp" #include "pros/vision.hpp" -#include "pros/link.hpp" -#include "pros/device.hpp" #endif #endif // _PROS_API_H_ diff --git a/include/pros/abstract_motor.hpp b/include/pros/abstract_motor.hpp new file mode 100644 index 000000000..071b1d74c --- /dev/null +++ b/include/pros/abstract_motor.hpp @@ -0,0 +1,1121 @@ +#ifndef _PROS_ABSTRACT_MOTORS_HPP_ +#define _PROS_ABSTRACT_MOTORS_HPP_ + +#include +#include + +#include "pros/device.hpp" +#include "pros/motors.h" +#include "rtos.hpp" + +namespace pros { +inline namespace v5 { + +/** + * \enum motor_brake + * Indicates the current 'brake mode' of a motor. + */ +enum class Motor_Brake { + /// Motor coasts when stopped, traditional behavior + coast = 0, + /// Motor brakes when stopped + brake = 1, + /// Motor actively holds position when stopped + hold = 2, + /// Invalid brake mode + invalid = INT32_MAX +}; + +/** + * \enum Motor_Encoder_Units + * Indicates the units used by the motor encoders. + */ +enum class Motor_Encoder_Units { + /// Position is recorded as angle in degrees as a floating point number + degrees = 0, + /// Position is recorded as angle in degrees as a floating point number + deg = 0, + /// Position is recorded as angle in rotations as a floating point number + rotations = 1, + /// Position is recorded as raw encoder ticks as a whole number + counts = 2, + /// Invalid motor encoder units + invalid = INT32_MAX +}; + +// Alias for Motor_Encoder_Units +using Motor_Units = Motor_Encoder_Units; + +enum class Motor_Gears { + /// 36:1, 100 RPM, Red gear set + ratio_36_to_1 = 0, + red = ratio_36_to_1, + rpm_100 = ratio_36_to_1, + /// 18:1, 200 RPM, Green gear set + ratio_18_to_1 = 1, + green = ratio_18_to_1, + rpm_200 = ratio_18_to_1, + /// 6:1, 600 RPM, Blue gear set + ratio_6_to_1 = 2, + blue = ratio_6_to_1, + rpm_600 = ratio_6_to_1, + /// Error return code + invalid = INT32_MAX +}; + +// Provide Aliases for Motor_Gears +using Motor_Gearset = Motor_Gears; +using Motor_Cart = Motor_Gears; +using Motor_Cartridge = Motor_Gears; +using Motor_Gear = Motor_Gears; + +/** + * \ingroup cpp-motors + */ +class AbstractMotor { + /** + * \addtogroup cpp-motors + * @{ + */ + public: + /// \name Motor movement functions + /// These functions allow programmers to make motors move + ///@{ + + /** + * Sets the voltage for the motor from -128 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of pros::Motor::move(), or motorSet from the PROS 2 API. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup MotorGroup ({1}, E_MOTOR_GEARSET_18); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t operator=(std::int32_t voltage) const = 0; + + /** + * Sets the voltage for the motor from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of motor_move(), or motorSet() from the PROS 2 API. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup MotorGroup ({1}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t move(std::int32_t voltage) const = 0; + + /** + * Sets the target absolute position for the motor to move to. + * + * This movement is relative to the position of the motor when initialized or + * the position when it was most recently reset with + * pros::Motor::set_zero_position(). + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The absolute position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * pros::delay(2); + * } + * motor.move_absolute(100, 100); // This does not cause a movement + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * pros::delay(2); + * } + * motor.tare_position(); + * motor.move_absolute(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t move_absolute(const double position, const std::int32_t velocity) const = 0; + + /** + * Sets the relative target position for the motor to move to. + * + * This movement is relative to the current position of the motor as given in + * pros::Motor::motor_get_position(). Providing 10.0 as the position parameter + * would result in the motor moving clockwise 10 units, no matter what the + * current position is. + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The relative position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_relative(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * pros::delay(2); + * } + * motor.move_relative(100, 100); // Also moves 100 units forward + * while (!((motor.get_position() < 205) && (motor.get_position() > 195))) { + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t move_relative(const double position, const std::int32_t velocity) const = 0; + + /** + * Sets the velocity for the motor. + * + * This velocity corresponds to different actual speeds depending on the + * gearset used for the motor. This results in a range of +-100 for + * E_MOTOR_GEARSET_36, +-200 for E_MOTOR_GEARSET_18, and +-600 for + * E_MOTOR_GEARSET_6. The velocity is held with PID to ensure consistent + * speed, as opposed to setting the motor's voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param velocity + * The new motor velocity from -+-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_velocity(100); + * pros::delay(1000); // Move at 100 RPM for 1 second + * motor.move_velocity(0); + * } + * \endcode + */ + virtual std::int32_t move_velocity(const std::int32_t velocity) const = 0; + + /** + * Sets the output voltage for the motor from -12000 to 12000 in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * \param voltage + * The new voltage value from -12000 to 12000 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor.move_voltage(12000); + * pros::delay(1000); // Move at max voltage for 1 second + * motor.move_voltage(0); + * } + * \endcode + */ + virtual std::int32_t move_voltage(const std::int32_t voltage) const = 0; + + virtual std::int32_t brake(void) const = 0; + virtual std::int32_t modify_profiled_velocity(const std::int32_t velocity) const = 0; + /** + * Gets the target position set for the motor by the user, with a parameter + * for the motor index. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index The index of the motor to get the target position of. + * + * \return The target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); + * std::cout << "Motor Target: " << motor.get_target_position(); + * // Prints 100 + * } + * \endcode + */ + virtual double get_target_position(const std::uint8_t index = 0) const = 0; + virtual std::vector get_target_position_all(void) const = 0; + + /** + * Gets the velocity commanded to the motor by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The commanded motor velocity from +-100, +-200, or +-600, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * std::cout << "Motor Velocity: " << motor.get_target_velocity(); + * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t get_target_velocity(const std::uint8_t index = 0) const = 0; + virtual std::vector get_target_velocity_all(void) const = 0; + + ///@} + + /// \name Motor telemetry functions + /// These functions allow programmers to collect telemetry from motors + ///@{ + + /** + * Gets the actual velocity of the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y); + * printf("Actual velocity: %lf\n", motor.get_actual_velocity()); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual double get_actual_velocity(const std::uint8_t index = 0) const = 0; + virtual std::vector get_actual_velocity_all(void) const = 0; + + /** + * Gets the current drawn by the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Current Draw: " << motor.get_current_draw(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t get_current_draw(const std::uint8_t index = 0) const = 0; + virtual std::vector get_current_draw_all(void) const = 0; + + /** + * Gets the direction of movement for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Direction: " << motor.get_direction(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t get_direction(const std::uint8_t index = 0) const = 0; + virtual std::vector get_direction_all(void) const = 0; + + /** + * Gets the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Efficiency: " << motor.get_efficiency(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual double get_efficiency(const std::uint8_t index = 0) const = 0; + virtual std::vector get_efficiency_all(void) const = 0; + + /** + * Gets the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * + * \return A bitfield containing the motor's faults. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults();pros::delay(2); + * } + * } + * \endcode + */ + virtual std::uint32_t get_faults(const std::uint8_t index = 0) const = 0; + virtual std::vector get_faults_all(void) const = 0; + /** + * Gets the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * + * \return A bitfield containing the motor's flags. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::uint32_t get_flags(const std::uint8_t index = 0) const = 0; + virtual std::vector get_flags_all(void) const = 0; + + /** + * Gets the absolute position of the motor in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_position(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual double get_position(const std::uint8_t index = 0) const = 0; + virtual std::vector get_position_all(void) const = 0; + + /** + * Gets the power drawn by the motor in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Power: " << motor.get_power(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual double get_power(const std::uint8_t index = 0) const = 0; + virtual std::vector get_power_all(void) const = 0; + /** + * Gets the raw encoder count of the motor at a given timestamp. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param[in] timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + * + * \b Example + * \code + * void opcontrol() { + * std::uint32_t now = pros::millis(); + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_raw_position(&now); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const = 0; + virtual std::vector get_raw_position_all(std::uint32_t* const timestamp) const = 0; + + /** + * Gets the temperature of the motor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Temperature: " << motor.get_temperature(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual double get_temperature(const std::uint8_t index = 0) const = 0; + virtual std::vector get_temperature_all(void) const = 0; + /** + * Gets the torque generated by the motor in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Torque: " << motor.get_torque(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual double get_torque(const std::uint8_t index = 0) const = 0; + virtual std::vector get_torque_all(void) const = 0; + /** + * Gets the voltage delivered to the motor in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Voltage: " << motor.get_voltage(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t get_voltage(const std::uint8_t index = 0) const = 0; + virtual std::vector get_voltage_all(void) const = 0; + + /** + * Checks if the motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its current limit?: " << motor.is_over_current(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t is_over_current(const std::uint8_t index = 0) const = 0; + virtual std::vector is_over_current_all(void) const = 0; + + /** + * Gets the temperature limit flag for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t is_over_temp(const std::uint8_t index = 0) const = 0; + virtual std::vector is_over_temp_all(void) const = 0; + + ///@} + + /// \name Motor configuration functions + /// These functions allow programmers to configure the behavior of motors + ///@{ + + /** + * Gets the brake mode that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return One of Motor_Brake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + virtual Motor_Brake get_brake_mode(const std::uint8_t index = 0) const = 0; + virtual std::vector get_brake_mode_all(void) const = 0; + + /** + * Gets the current limit for the motor in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * while (true) { + * std::cout << "Motor Current Limit: " << motor.get_current_limit(); + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t get_current_limit(const std::uint8_t index = 0) const = 0; + virtual std::vector get_current_limit_all(void) const = 0; + + /** + * Gets the encoder units that were set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return One of Motor_Units according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + virtual Motor_Units get_encoder_units(const std::uint8_t index = 0) const = 0; + virtual std::vector get_encoder_units_all(void) const = 0; + + /** + * Gets the gearset that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return One of Motor_Gears according to what is set for the motor, + * or pros::Motor_Gears::invalid if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Gearing: " << motor.get_gearing(); + * } + * \endcode + */ + virtual Motor_Gears get_gearing(const std::uint8_t index = 0) const = 0; + virtual std::vector get_gearing_all(void) const = 0; + + /** + * @brief Gets returns a vector with all the port numbers in the motor group. + * + * @return std::vector + */ + virtual std::vector get_port_all(void) const = 0; + + /** + * Gets the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Motor Voltage Limit: " << motor.get_voltage_limit(); + * } + * \endcode + */ + virtual std::int32_t get_voltage_limit(const std::uint8_t index = 0) const = 0; + virtual std::vector get_voltage_limit_all(void) const = 0; + + /** + * Gets the operation direction of the motor as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Is the motor reversed? " << motor.is_reversed(); + * // Prints "0" + * } + * \endcode + */ + virtual std::int32_t is_reversed(const std::uint8_t index = 0) const = 0; + virtual std::vector is_reversed_all(void) const = 0; + + /** + * Sets one of Motor_Brake to the motor. Works with the C enum + * and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param mode + * The Motor_Brake to set for the motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + virtual std::int32_t set_brake_mode(const Motor_Brake mode, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_brake_mode_all(const Motor_Brake mode) const = 0; + virtual std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const = 0; + /** + * Sets the current limit for the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new current limit in mA + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_current_limit(1000); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_current_limit_all(const std::int32_t limit) const = 0; + /** + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + virtual std::int32_t set_encoder_units(const Motor_Units units, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_encoder_units_all(const Motor_Units units) const = 0; + virtual std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const = 0; + /** + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param gearset + * The new motor gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_gearing(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); + * } + * \endcode + */ + virtual std::int32_t set_gearing(const Motor_Gears gearset, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_gearing_all(const Motor_Gears gearset) const = 0; + virtual std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const = 0; + + /** + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param reverse + * True reverses the motor, false is default + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_reversed(true); + * std::cout << "Is this motor reversed? " << motor.is_reversed(); + * } + * \endcode + */ + virtual std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0) = 0; + virtual std::int32_t set_reversed_all(const bool reverse) = 0; + + /** + * Sets the voltage limit for the motor in Volts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new voltage limit in Volts + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_voltage_limit(10000); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will not output more than 10 V + * pros::delay(2); + * } + * } + * \endcode + */ + virtual std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_voltage_limit_all(const std::int32_t limit) const = 0; + + /** + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The new reference position in its encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.set_zero_position(80); + * motor.move_absolute(100, 100); // Moves 80 units forward + * } + * \endcode + * + */ + virtual std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const = 0; + virtual std::int32_t set_zero_position_all(const double position) const = 0; + + /** + * Sets the "absolute" zero position of the motor to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.tare_position(); + * motor.move_absolute(100, 100); // Moves 100 units forward + * } + * \endcode + */ + virtual std::int32_t tare_position(const std::uint8_t index = 0) const = 0; + virtual std::int32_t tare_position_all(void) const = 0; + virtual std::int8_t get_port(const std::uint8_t index = 0) const = 0; + /** + * @brief Returns the number of objects + * + * @return std::int8_t + */ + virtual std::int8_t size(void) const = 0; + + ///@} + private: +}; + +///@} + +} // namespace v5 +} // namespace pros + +#endif \ No newline at end of file diff --git a/include/pros/motor_group.hpp b/include/pros/motor_group.hpp new file mode 100644 index 000000000..c90ccca54 --- /dev/null +++ b/include/pros/motor_group.hpp @@ -0,0 +1,1122 @@ +/** + * \file pros/motors.hpp + * \ingroup cpp-motors + * + * Contains prototypes for the V5 Motor-related functions. + * + * Visit https://pros.cs.purdue.edu/v5/tutorials/topical/motors.html to learn + * more. + * + * This file should not be modified by users, since it gets replaced whenever + * a kernel upgrade occurs. + * + * \copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \defgroup cpp-motors Motors C++ API + * \note Additional example code for this module can be found in its [Tutorial](@ref motors). + */ + +#ifndef _PROS_MOTOR_GROUP_HPP_ +#define _PROS_MOTOR_GROUP_HPP_ + +#include +#include + +#include "pros/abstract_motor.hpp" +#include "pros/colors.hpp" +#include "pros/device.hpp" +#include "pros/motors.h" +#include "pros/motors.hpp" +#include "rtos.hpp" + +namespace pros { +inline namespace v5 { +class MotorGroup : public virtual AbstractMotor { + /** + * \addtogroup cpp-motors + * @{ + */ + public: + explicit MotorGroup(const std::initializer_list, const pros::v5::Motor_Gears gearset = pros::v5::Motor_Gears::green, + const pros::v5::Motor_Units encoder_units = pros::v5::Motor_Units::degrees); + explicit MotorGroup(const std::vector& ports, const pros::v5::Motor_Gears gearset = pros::v5::Motor_Gears::green, + const pros::v5::Motor_Units encoder_units = pros::v5::Motor_Units::degrees); + std::int32_t operator=(const std::int32_t); + + /// \name Motor movement functions + /// These functions allow programmers to make motors move + ///@{ + + /** + * Sets the voltage for the motor from -128 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of pros::Motor::move(), or motorSet from the PROS 2 API. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup MotorGroup ({1}, E_MOTOR_GEARSET_18); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t operator=(std::int32_t voltage) const; + + /** + * Sets the voltage for the motor from -127 to 127. + * + * This is designed to map easily to the input from the controller's analog + * stick for simple opcontrol use. The actual behavior of the motor is + * analogous to use of motor_move(), or motorSet() from the PROS 2 API. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param voltage + * The new motor voltage from -127 to 127 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::MotorGroup MotorGroup ({1}); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move(std::int32_t voltage) const; + + /** + * Sets the target absolute position for the motor to move to. + * + * This movement is relative to the position of the motor when initialized or + * the position when it was most recently reset with + * pros::Motor::set_zero_position(). + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The absolute position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * pros::delay(2); + * } + * motor.move_absolute(100, 100); // This does not cause a movement + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * pros::delay(2); + * } + * motor.tare_position(); + * motor.move_absolute(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move_absolute(const double position, const std::int32_t velocity) const; + + /** + * Sets the relative target position for the motor to move to. + * + * This movement is relative to the current position of the motor as given in + * pros::Motor::motor_get_position(). Providing 10.0 as the position parameter + * would result in the motor moving clockwise 10 units, no matter what the + * current position is. + * + * \note This function simply sets the target for the motor, it does not block + * program execution until the movement finishes. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The relative position to move to in the motor's encoder units + * \param velocity + * The maximum allowable velocity for the movement in RPM + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_relative(100, 100); // Moves 100 units forward + * while (!((motor.get_position() < 105) && (motor.get_position() > 95))) { + * // Continue running this loop as long as the motor is not within +-5 units of its goal + * pros::delay(2); + * } + * motor.move_relative(100, 100); // Also moves 100 units forward + * while (!((motor.get_position() < 205) && (motor.get_position() > 195))) { + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t move_relative(const double position, const std::int32_t velocity) const; + + /** + * Sets the velocity for the motor. + * + * This velocity corresponds to different actual speeds depending on the + * gearset used for the motor. This results in a range of +-100 for + * E_MOTOR_GEARSET_36, +-200 for E_MOTOR_GEARSET_18, and +-600 for + * E_MOTOR_GEARSET_6. The velocity is held with PID to ensure consistent + * speed, as opposed to setting the motor's voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param velocity + * The new motor velocity from -+-100, +-200, or +-600 depending on the + * motor's gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_velocity(100); + * pros::delay(1000); // Move at 100 RPM for 1 second + * motor.move_velocity(0); + * } + * \endcode + */ + std::int32_t move_velocity(const std::int32_t velocity) const; + + /** + * Sets the output voltage for the motor from -12000 to 12000 in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * \param voltage + * The new voltage value from -12000 to 12000 + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * motor.move_voltage(12000); + * pros::delay(1000); // Move at max voltage for 1 second + * motor.move_voltage(0); + * } + * \endcode + */ + std::int32_t move_voltage(const std::int32_t voltage) const; + + std::int32_t brake(void) const; + + std::int32_t modify_profiled_velocity(const std::int32_t velocity) const; + /** + * Gets the target position set for the motor by the user, with a parameter + * for the motor index. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param index The index of the motor to get the target position of. + * + * \return The target position in its encoder units or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); + * std::cout << "Motor Target: " << motor.get_target_position(); + * // Prints 100 + * } + * \endcode + */ + double get_target_position(const std::uint8_t index) const; + std::vector get_target_position_all(void) const; + + /** + * Gets the velocity commanded to the motor by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The commanded motor velocity from +-100, +-200, or +-600, or + * PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor.move_velocity(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); + * std::cout << "Motor Velocity: " << motor.get_target_velocity(); + * // Prints the value of E_CONTROLLER_ANALOG_LEFT_Y + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_target_velocity(const std::uint8_t index = 0) const; + std::vector get_target_velocity_all(void) const; + + ///@} + + /// \name Motor telemetry functions + /// These functions allow programmers to collect telemetry from motors + ///@{ + + /** + * Gets the actual velocity of the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's actual velocity in RPM or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_MASTER, E_CONTROLLER_ANALOG_LEFT_Y); + * printf("Actual velocity: %lf\n", motor.get_actual_velocity()); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_actual_velocity(const std::uint8_t index = 0) const; + std::vector get_actual_velocity_all(void) const; + + /** + * Gets the current drawn by the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's current in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Current Draw: " << motor.get_current_draw(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_current_draw(const std::uint8_t index = 0) const; + std::vector get_current_draw_all(void) const; + + /** + * Gets the direction of movement for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 for moving in the positive direction, -1 for moving in the + * negative direction, and PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Direction: " << motor.get_direction(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_direction(const std::uint8_t index = 0) const; + std::vector get_direction_all(void) const; + + /** + * Gets the efficiency of the motor in percent. + * + * An efficiency of 100% means that the motor is moving electrically while + * drawing no electrical power, and an efficiency of 0% means that the motor + * is drawing power but not moving. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's efficiency in percent or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Efficiency: " << motor.get_efficiency(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_efficiency(const std::uint8_t index = 0) const; + std::vector get_efficiency_all(void) const; + + /** + * Gets the faults experienced by the motor. + * + * Compare this bitfield to the bitmasks in pros::motor_fault_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * + * \return A bitfield containing the motor's faults. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults();pros::delay(2); + * } + * } + * \endcode + */ + std::uint32_t get_faults(const std::uint8_t index = 0) const; + std::vector get_faults_all(void) const; + /** + * Gets the flags set by the motor's operation. + * + * Compare this bitfield to the bitmasks in pros::motor_flag_e_t. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param port + * The V5 port number from 1-21 + * + * \return A bitfield containing the motor's flags. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Faults: " << motor.get_faults(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::uint32_t get_flags(const std::uint8_t index = 0) const; + std::vector get_flags_all(void) const; + + /** + * Gets the absolute position of the motor in its encoder units. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's absolute position in its encoder units or PROS_ERR_F + * if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_position(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_position(const std::uint8_t index = 0) const; + std::vector get_position_all(void) const; + + /** + * Gets the power drawn by the motor in Watts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's power draw in Watts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Power: " << motor.get_power(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_power(const std::uint8_t index = 0) const; + std::vector get_power_all(void) const; + /** + * Gets the raw encoder count of the motor at a given timestamp. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param[in] timestamp + * A pointer to a time in milliseconds for which the encoder count + * will be returned. If NULL, the timestamp at which the encoder + * count was read will not be supplied + * + * \return The raw encoder count at the given timestamp or PROS_ERR if the + * operation failed. + * + * \b Example + * \code + * void opcontrol() { + * std::uint32_t now = pros::millis(); + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Position: " << motor.get_raw_position(&now); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const; + std::vector get_raw_position_all(std::uint32_t* const timestamp) const; + + /** + * Gets the temperature of the motor in degrees Celsius. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Temperature: " << motor.get_temperature(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_temperature(const std::uint8_t index = 0) const; + std::vector get_temperature_all(void) const; + /** + * Gets the torque generated by the motor in Newton Meters (Nm). + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's torque in Nm or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Torque: " << motor.get_torque(); + * pros::delay(2); + * } + * } + * \endcode + */ + double get_torque(const std::uint8_t index = 0) const; + std::vector get_torque_all(void) const; + /** + * Gets the voltage delivered to the motor in millivolts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Motor Voltage: " << motor.get_voltage(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_voltage(const std::uint8_t index = 0) const; + std::vector get_voltage_all(void) const; + + /** + * Checks if the motor is drawing over its current limit. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the motor's current limit is being exceeded and 0 if the + * current limit is not exceeded, or PROS_ERR if the operation failed, setting + * errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its current limit?: " << motor.is_over_current(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t is_over_current(const std::uint8_t index = 0) const; + std::vector is_over_current_all(void) const; + + /** + * Gets the temperature limit flag for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the temperature limit is exceeded and 0 if the temperature is + * below the limit, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * std::cout << "Is the motor over its temperature limit?: " << motor.is_over_temp(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t is_over_temp(const std::uint8_t index = 0) const; + std::vector is_over_temp_all(void) const; + + ///@} + + /// \name Motor configuration functions + /// These functions allow programmers to configure the behavior of motors + ///@{ + + /** + * Gets the brake mode that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return One of Motor_Brake, according to what was set for the + * motor, or E_MOTOR_BRAKE_INVALID if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + Motor_Brake get_brake_mode(const std::uint8_t index = 0) const; + std::vector get_brake_mode_all(void) const; + + /** + * Gets the current limit for the motor in mA. + * + * The default value is 2500 mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's current limit in mA or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * while (true) { + * std::cout << "Motor Current Limit: " << motor.get_current_limit(); + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t get_current_limit(const std::uint8_t index = 0) const; + std::vector get_current_limit_all(void) const; + + /** + * Gets the encoder units that were set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return One of Motor_Units according to what is set for the + * motor or E_MOTOR_ENCODER_INVALID if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + Motor_Units get_encoder_units(const std::uint8_t index = 0) const; + std::vector get_encoder_units_all(void) const; + + /** + * Gets the gearset that was set for the motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return One of Motor_Gears according to what is set for the motor, + * or pros::Motor_Gears::invalid if the operation failed. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1, E_MOTOR_GEARSET_06, false, E_MOTOR_ENCODER_COUNTS); + * std::cout << "Motor Gearing: " << motor.get_gearing(); + * } + * \endcode + */ + Motor_Gears get_gearing(const std::uint8_t index = 0) const; + std::vector get_gearing_all(void) const; + + /** + * @brief Gets returns a vector with all the port numbers in the motor group. + * (ALL THE PORTS WILL BE POSITIVE) + * Use get_ports if you want to get the information on reversal. + * + * @return std::vector + */ + std::vector get_port_all(void) const; + + /** + * Gets the voltage limit set by the user. + * + * Default value is 0V, which means that there is no software limitation + * imposed on the voltage. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return The motor's voltage limit in V or PROS_ERR if the operation failed, + * setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Motor Voltage Limit: " << motor.get_voltage_limit(); + * } + * \endcode + */ + std::int32_t get_voltage_limit(const std::uint8_t index = 0) const; + std::vector get_voltage_limit_all(void) const; + + /** + * Gets the operation direction of the motor as set by the user. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the motor has been reversed and 0 if the motor was not + * reversed, or PROS_ERR if the operation failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * std::cout << "Is the motor reversed? " << motor.is_reversed(); + * // Prints "0" + * } + * \endcode + */ + std::int32_t is_reversed(const std::uint8_t index = 0) const; + std::vector is_reversed_all(void) const; + + /** + * Sets one of Motor_Brake to the motor. Works with the C enum + * and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param mode + * The Motor_Brake to set for the motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_brake_mode(pros::E_MOTOR_BRAKE_HOLD); + * std::cout << "Brake Mode: " << motor.get_brake_mode(); + * } + * \endcode + */ + std::int32_t set_brake_mode(const Motor_Brake mode, const std::uint8_t index = 0) const; + std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const; + std::int32_t set_brake_mode_all(const Motor_Brake mode) const; + std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const; + /** + * Sets the current limit for the motor in mA. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new current limit in mA + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_current_limit(1000); + * while (true) { + * motor = controller_get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will reduce its output at 1000 mA instead of the default 2500 mA + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + std::int32_t set_current_limit_all(const std::int32_t limit) const; + /** + * Sets one of Motor_Units for the motor encoder. Works with the C + * enum and the C++ enum class. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param units + * The new motor encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_encoder_units(E_MOTOR_ENCODER_DEGREES); + * std::cout << "Encoder Units: " << motor.get_encoder_units(); + * } + * \endcode + */ + std::int32_t set_encoder_units(const Motor_Units units, const std::uint8_t index = 0) const; + std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const; + std::int32_t set_encoder_units_all(const Motor_Units units) const; + std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const; + /** + * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with + * the C++ enum class and the C enum. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param gearset + * The new motor gearset + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_gearing(E_MOTOR_GEARSET_06); + * std::cout << "Gearset: " << motor.get_gearing(); + * } + * \endcode + */ + std::int32_t set_gearing(const Motor_Gears gearset, const std::uint8_t index = 0) const; + std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const; + std::int32_t set_gearing_all(const Motor_Gears gearset) const; + std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const; + + /** + * Sets the reverse flag for the motor. + * + * This will invert its movements and the values returned for its position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param reverse + * True reverses the motor, false is default + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void initialize() { + * pros::Motor motor (1); + * motor.set_reversed(true); + * std::cout << "Is this motor reversed? " << motor.is_reversed(); + * } + * \endcode + */ + std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0); + std::int32_t set_reversed_all(const bool reverse); + + /** + * Sets the voltage limit for the motor in Volts. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param limit + * The new voltage limit in Volts + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * pros::Controller master (E_CONTROLLER_MASTER); + * + * motor.set_voltage_limit(10000); + * while (true) { + * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); + * // The motor will not output more than 10 V + * pros::delay(2); + * } + * } + * \endcode + */ + std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + std::int32_t set_voltage_limit_all(const std::int32_t limit) const; + + /** + * Sets the position for the motor in its encoder units. + * + * This will be the future reference point for the motor's "absolute" + * position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \param position + * The new reference position in its encoder units + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.set_zero_position(80); + * motor.move_absolute(100, 100); // Moves 80 units forward + * } + * \endcode + * + */ + std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const; + std::int32_t set_zero_position_all(const double position) const; + + /** + * Sets the "absolute" zero position of the motor to its current position. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * + * \return 1 if the operation was successful or PROS_ERR if the operation + * failed, setting errno. + * + * \b Example + * \code + * void autonomous() { + * pros::Motor motor (1); + * motor.move_absolute(100, 100); // Moves 100 units forward + * motor.move_absolute(100, 100); // This does not cause a movement + * + * motor.tare_position(); + * motor.move_absolute(100, 100); // Moves 100 units forward + * } + * \endcode + */ + std::int32_t tare_position(const std::uint8_t index = 0) const; + std::int32_t tare_position_all(void) const; + + /** + * @brief Returns the number of objects + * + * @return std::int8_t + */ + std::int8_t size(void) const; + std::int8_t get_port(const std::uint8_t index = 0) const; + + /** + * @brief Appends the other motor group reference to this motor group + * + */ + void operator+=(MotorGroup&); + + /** + * @brief Appends the other motor group reference to this motor group + * + */ + void append(MotorGroup&); + + /** + * @brief Removes the port (and it's reversed ) + * + * @param port + */ + void erase_port(std::int8_t port); + + /** + * This is the overload for the << operator for printing to streams + * + * Prints in format: + * Motor [port: (motor port), brake mode: (brake mode), current draw: (current draw), + * current limit: (current limit), direction: (direction), efficiency: (efficiency), + * encoder units: (encoder units), gearing: (gearing), is over temp: (over temp), + * position: (position), reversed: (reversed boolean), temperature: (temperature), + * torque: (torque), voltage: (voltage)] + */ + friend std::ostream& operator<<(std::ostream& os, pros::MotorGroup& motor); + ///@} + private: + std::vector _ports; + mutable pros::Mutex _MotorGroup_mutex; +}; +} // namespace v5 +} // namespace pros +#endif \ No newline at end of file diff --git a/include/pros/motors.hpp b/include/pros/motors.hpp index 7eacc41d6..bb5a3aab4 100644 --- a/include/pros/motors.hpp +++ b/include/pros/motors.hpp @@ -26,6 +26,7 @@ #include #include +#include "pros/abstract_motor.hpp" #include "pros/device.hpp" #include "pros/motors.h" #include "rtos.hpp" @@ -33,124 +34,15 @@ namespace pros { inline namespace v5 { -/** - * \enum motor_brake - * Indicates the current 'brake mode' of a motor. - */ -enum class Motor_Brake { - /// Motor coasts when stopped, traditional behavior - coast = 0, - /// Motor brakes when stopped - brake = 1, - /// Motor actively holds position when stopped - hold = 2, - /// Invalid brake mode - invalid = INT32_MAX -}; - -/** - * \enum Motor_Encoder_Units - * Indicates the units used by the motor encoders. - */ -enum class Motor_Encoder_Units { - /// Position is recorded as angle in degrees as a floating point number - degrees = 0, - /// Position is recorded as angle in degrees as a floating point number - deg = 0, - /// Position is recorded as angle in rotations as a floating point number - rotations = 1, - /// Position is recorded as raw encoder ticks as a whole number - counts = 2, - /// Invalid motor encoder units - invalid = INT32_MAX -}; - -// Alias for Motor_Encoder_Units -using Motor_Units = Motor_Encoder_Units; - -enum class Motor_Gears { - /// 36:1, 100 RPM, Red gear set - ratio_36_to_1 = 0, - red = ratio_36_to_1, - rpm_100 = ratio_36_to_1, - /// 18:1, 200 RPM, Green gear set - ratio_18_to_1 = 1, - green = ratio_18_to_1, - rpm_200 = ratio_18_to_1, - /// 6:1, 600 RPM, Blue gear set - ratio_6_to_1 = 2, - blue = ratio_6_to_1, - rpm_600 = ratio_6_to_1, - /// Error return code - invalid = INT32_MAX -}; - -// Provide Aliases for Motor_Gears -using Motor_Gearset = Motor_Gears; -using Motor_Cart = Motor_Gears; -using Motor_Cartridge = Motor_Gears; -using Motor_Gear = Motor_Gears; +class Motor : public AbstractMotor, public Device { + public: + explicit Motor(const std::int8_t port, const pros::v5::Motor_Gears gearset = pros::v5::Motor_Gears::green, + const pros::v5::Motor_Units encoder_units = pros::v5::Motor_Units::degrees); -/** - * \ingroup cpp-motors - */ -class Motor_Group { /** * \addtogroup cpp-motors * @{ */ - public: - /** - * Creates a Motor object for the given port and specifications. - * - * This function uses the following values of errno when an error state is - * reached: - * ENXIO - The given value is not within the range of V5 ports (1-21). - * ENODEV - The port cannot be configured as a motor - * - * \param port - * The V5 port number from 1-21 - * \param gearset - * The motor's gearset - * \param reverse - * True reverses the motor, false is default - * \param encoder_units - * The motor's encoder units - * - * \b Example - * \code - * void opcontrol() { - * pros::Motor motor (1, E_MOTOR_GEARSET_18, false, E_MOTOR_ENCODER_DEGREES); - * pros::Controller master (E_CONTROLLER_MASTER); - * while (true) { - * motor.move(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); - * pros::delay(2); - * } - * } - * \endcode - */ - explicit Motor_Group(std::initializer_list ports, const Motor_Gears gearset, const bool reverse, - const Motor_Units encoder_units); - - explicit Motor_Group(std::initializer_list ports, const Motor_Gears gearset, const bool reverse); - - explicit Motor_Group(std::initializer_list ports, const Motor_Gears gearset); - - explicit Motor_Group(std::initializer_list ports, const bool reverse); - - explicit Motor_Group(std::initializer_list ports); - - explicit Motor_Group(std::vector ports, const Motor_Gears gearset, const bool reverse, - const Motor_Units encoder_units); - - explicit Motor_Group(std::vector ports, const Motor_Gears gearset, const bool reverse); - - explicit Motor_Group(std::vector ports, const Motor_Gears gearset); - - explicit Motor_Group(std::vector ports, const bool reverse); - - explicit Motor_Group(std::vector ports); - /// \name Motor movement functions /// These functions allow programmers to make motors move ///@{ @@ -175,7 +67,7 @@ class Motor_Group { * \b Example * \code * void opcontrol() { - * pros::Motor_Group motor_group ({1}, E_MOTOR_GEARSET_18); + * pros::MotorGroup MotorGroup ({1}, E_MOTOR_GEARSET_18); * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor = master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y); @@ -206,7 +98,7 @@ class Motor_Group { * \b Example * \code * void opcontrol() { - * pros::Motor_Group motor_group ({1}); + * pros::MotorGroup MotorGroup ({1}); * pros::Controller master (E_CONTROLLER_MASTER); * while (true) { * motor.move(master.get_analog(E_CONTROLLER_ANALOG_LEFT_Y)); @@ -361,58 +253,18 @@ class Motor_Group { */ std::int32_t move_voltage(const std::int32_t voltage) const; - /** - * Stops the motor using the currently configured brake mode. - * - * This function sets motor velocity to zero, which will cause it to act - * according to the set brake mode. If brake mode is set to MOTOR_BRAKE_HOLD, - * this function may behave differently than calling move_absolute(0) - * or move_relative(0). - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - */ std::int32_t brake(void) const; - - /** - * Changes the output velocity for a profiled movement (motor_move_absolute() - * or motor_move_relative()). This will have no effect if the motor is not - * following a profiled movement. - * - * This function uses the following values of errno when an error state is - * reached: - * ENODEV - The port cannot be configured as a motor - * - * \param velocity - * The new motor velocity from +-100, +-200, or +-600 depending on the - * motor's gearset - * - * \return 1 if the operation was successful or PROS_ERR if the operation - * failed, setting errno. - * - * \b Example - * \code - * void autonomous() { - * pros::Motor motor (1); - * motor.move_absolute(1, 100, 100); - * pros::delay(100); - * motor.modify_profiled_velocity(1, 0); // Stop the motor early - * } - * \endcode - */ std::int32_t modify_profiled_velocity(const std::int32_t velocity) const; - /** - * Gets the target position set for the motor by the user. + * Gets the target position set for the motor by the user, with a parameter + * for the motor index. * * This function uses the following values of errno when an error state is * reached: * ENODEV - The port cannot be configured as a motor * + * \param index The index of the motor to get the target position of. + * * \return The target position in its encoder units or PROS_ERR_F if the * operation failed, setting errno. * @@ -426,10 +278,8 @@ class Motor_Group { * } * \endcode */ - double get_target_position(void) const; - double get_target_position(std::uint8_t) const; - - std::vector get_every_target_position(void) const; + double get_target_position(const std::uint8_t index = 0) const; + std::vector get_target_position_all(void) const; /** * Gets the velocity commanded to the motor by the user. @@ -455,10 +305,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t get_target_velocity(void) const; - std::int32_t get_target_velocity(std::uint8_t) const; - - std::vector get_every_target_velocity(void) const; + std::int32_t get_target_velocity(const std::uint8_t index = 0) const; + std::vector get_target_velocity_all(void) const; ///@} @@ -488,10 +336,8 @@ class Motor_Group { * } * \endcode */ - double get_actual_velocity(void) const; - double get_actual_velocity(std::uint8_t) const; - - std::vector get_every_actual_velocity(void) const; + double get_actual_velocity(const std::uint8_t index = 0) const; + std::vector get_actual_velocity_all(void) const; /** * Gets the current drawn by the motor in mA. @@ -516,9 +362,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t get_current_draw(void) const; - std::int32_t get_current_draw(std::uint8_t) const; - std::vector get_every_current_draw(void) const; + std::int32_t get_current_draw(const std::uint8_t index = 0) const; + std::vector get_current_draw_all(void) const; /** * Gets the direction of movement for the motor. @@ -543,9 +388,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t get_direction(void) const; - std::int32_t get_direction(std::uint8_t) const; - std::vector get_every_direction(void) const; + std::int32_t get_direction(const std::uint8_t index = 0) const; + std::vector get_direction_all(void) const; /** * Gets the efficiency of the motor in percent. @@ -574,9 +418,8 @@ class Motor_Group { * } * \endcode */ - double get_efficiency(void) const; - double get_efficiency(std::uint8_t) const; - std::vector get_every_efficiency(void) const; + double get_efficiency(const std::uint8_t index = 0) const; + std::vector get_efficiency_all(void) const; /** * Gets the faults experienced by the motor. @@ -604,9 +447,8 @@ class Motor_Group { * } * \endcode */ - std::uint32_t get_faults(void) const; - std::uint32_t get_faults(std::uint8_t) const; - std::vector get_every_faults(void) const; + std::uint32_t get_faults(const std::uint8_t index = 0) const; + std::vector get_faults_all(void) const; /** * Gets the flags set by the motor's operation. * @@ -634,9 +476,8 @@ class Motor_Group { * } * \endcode */ - std::uint32_t get_flags(void) const; - std::uint32_t get_flags(std::uint8_t) const; - std::vector get_every_flags(void) const; + std::uint32_t get_flags(const std::uint8_t index = 0) const; + std::vector get_flags_all(void) const; /** * Gets the absolute position of the motor in its encoder units. @@ -661,9 +502,8 @@ class Motor_Group { * } * \endcode */ - double get_position(void) const; - double get_position(std::uint8_t) const; - std::vector get_every_position(void) const; + double get_position(const std::uint8_t index = 0) const; + std::vector get_position_all(void) const; /** * Gets the power drawn by the motor in Watts. @@ -688,9 +528,8 @@ class Motor_Group { * } * \endcode */ - double get_power(void) const; - double get_power(std::uint8_t) const; - std::vector get_every_power(void) const; + double get_power(const std::uint8_t index = 0) const; + std::vector get_power_all(void) const; /** * Gets the raw encoder count of the motor at a given timestamp. * @@ -720,9 +559,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t get_raw_position(std::uint32_t* const timestamp) const; - std::int32_t get_raw_position(std::uint32_t* const timestamp, std::uint8_t) const; - std::vector get_every_raw_position(std::uint32_t* const timestamp) const; + std::int32_t get_raw_position(std::uint32_t* const timestamp, const std::uint8_t index = 0) const; + std::vector get_raw_position_all(std::uint32_t* const timestamp) const; /** * Gets the temperature of the motor in degrees Celsius. @@ -747,9 +585,8 @@ class Motor_Group { * } * \endcode */ - double get_temperature(void) const; - double get_temperature(std::uint8_t) const; - std::vector get_every_temperature(void) const; + double get_temperature(const std::uint8_t index = 0) const; + std::vector get_temperature_all(void) const; /** * Gets the torque generated by the motor in Newton Meters (Nm). * @@ -773,9 +610,8 @@ class Motor_Group { * } * \endcode */ - double get_torque(void) const; - double get_torque(std::uint8_t) const; - std::vector get_every_torque(void) const; + double get_torque(const std::uint8_t index = 0) const; + std::vector get_torque_all(void) const; /** * Gets the voltage delivered to the motor in millivolts. * @@ -799,9 +635,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t get_voltage(void) const; - std::int32_t get_voltage(std::uint8_t) const; - std::vector get_every_voltage(void) const; + std::int32_t get_voltage(const std::uint8_t index = 0) const; + std::vector get_voltage_all(void) const; /** * Checks if the motor is drawing over its current limit. @@ -827,9 +662,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t is_over_current(void) const; - std::int32_t is_over_current(std::uint8_t) const; - std::vector every_is_over_current(void) const; + std::int32_t is_over_current(const std::uint8_t index = 0) const; + std::vector is_over_current_all(void) const; /** * Gets the temperature limit flag for the motor. @@ -854,9 +688,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t is_over_temp(void) const; - std::int32_t is_over_temp(std::uint8_t) const; - std::vector every_is_over_temp(void) const; + std::int32_t is_over_temp(const std::uint8_t index = 0) const; + std::vector is_over_temp_all(void) const; ///@} @@ -883,9 +716,8 @@ class Motor_Group { * } * \endcode */ - Motor_Brake get_brake_mode(void) const; - Motor_Brake get_brake_mode(std::uint8_t) const; - std::vector get_every_brake_mode(void) const; + Motor_Brake get_brake_mode(const std::uint8_t index = 0) const; + std::vector get_brake_mode_all(void) const; /** * Gets the current limit for the motor in mA. @@ -910,9 +742,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t get_current_limit(void) const; - std::int32_t get_current_limit(std::uint8_t) const; - std::vector get_every_current_limit(void) const; + std::int32_t get_current_limit(const std::uint8_t index = 0) const; + std::vector get_current_limit_all(void) const; /** * Gets the encoder units that were set for the motor. @@ -932,9 +763,8 @@ class Motor_Group { * } * \endcode */ - Motor_Units get_encoder_units(void) const; - Motor_Units get_encoder_units(std::uint8_t) const; - std::vector get_every_encoder_units(void) const; + Motor_Units get_encoder_units(const std::uint8_t index = 0) const; + std::vector get_encoder_units_all(void) const; /** * Gets the gearset that was set for the motor. @@ -954,18 +784,15 @@ class Motor_Group { * } * \endcode */ - Motor_Gears get_gearing(void) const; - Motor_Gears get_gearing(std::uint8_t) const; - std::vector get_every_gearing(void) const; + Motor_Gears get_gearing(const std::uint8_t index = 0) const; + std::vector get_gearing_all(void) const; /** * @brief Gets returns a vector with all the port numbers in the motor group. - * (ALL THE PORTS WILL BE POSITIVE) - * Use get_ports if you want to get the information on reversal. * * @return std::vector */ - std::vector get_every_port(void) const; + std::vector get_port_all(void) const; /** * Gets the voltage limit set by the user. @@ -988,9 +815,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t get_voltage_limit(void) const; - std::int32_t get_voltage_limit(std::uint8_t) const; - std::vector get_every_voltage_limit(void) const; + std::int32_t get_voltage_limit(const std::uint8_t index = 0) const; + std::vector get_voltage_limit_all(void) const; /** * Gets the operation direction of the motor as set by the user. @@ -1011,9 +837,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t is_reversed(void) const; - std::int32_t is_reversed(std::uint8_t) const; - std::vector every_is_reversed(void) const; + std::int32_t is_reversed(const std::uint8_t index = 0) const; + std::vector is_reversed_all(void) const; /** * Sets one of Motor_Brake to the motor. Works with the C enum @@ -1038,9 +863,10 @@ class Motor_Group { * } * \endcode */ - std::int32_t set_brake_mode(const Motor_Brake mode) const; - std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode) const; - + std::int32_t set_brake_mode(const Motor_Brake mode, const std::uint8_t index = 0) const; + std::int32_t set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index = 0) const; + std::int32_t set_brake_mode_all(const Motor_Brake mode) const; + std::int32_t set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const; /** * Sets the current limit for the motor in mA. * @@ -1069,8 +895,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t set_current_limit(const std::int32_t limit) const; - + std::int32_t set_current_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + std::int32_t set_current_limit_all(const std::int32_t limit) const; /** * Sets one of Motor_Units for the motor encoder. Works with the C * enum and the C++ enum class. @@ -1094,9 +920,10 @@ class Motor_Group { * } * \endcode */ - std::int32_t set_encoder_units(const Motor_Units units); - std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units); - + std::int32_t set_encoder_units(const Motor_Units units, const std::uint8_t index = 0) const; + std::int32_t set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index = 0) const; + std::int32_t set_encoder_units_all(const Motor_Units units) const; + std::int32_t set_encoder_units_all(const pros::motor_encoder_units_e_t units) const; /** * Sets one of the gear cartridge (red, green, blue) for the motor. Usable with * the C++ enum class and the C enum. @@ -1120,8 +947,11 @@ class Motor_Group { * } * \endcode */ - std::int32_t set_gearing(const Motor_Gears gearset); - std::int32_t set_gearing(const pros::motor_gearset_e_t gearset); + std::int32_t set_gearing(const Motor_Gears gearset, const std::uint8_t index = 0) const; + std::int32_t set_gearing(const pros::motor_gearset_e_t gearset, const std::uint8_t index = 0) const; + std::int32_t set_gearing_all(const Motor_Gears gearset) const; + std::int32_t set_gearing_all(const pros::motor_gearset_e_t gearset) const; + /** * Sets the reverse flag for the motor. @@ -1147,7 +977,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t set_reversed(const bool reverse); + std::int32_t set_reversed(const bool reverse, const std::uint8_t index = 0); + std::int32_t set_reversed_all(const bool reverse); /** * Sets the voltage limit for the motor in Volts. @@ -1177,7 +1008,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t set_voltage_limit(const std::int32_t limit) const; + std::int32_t set_voltage_limit(const std::int32_t limit, const std::uint8_t index = 0) const; + std::int32_t set_voltage_limit_all(const std::int32_t limit) const; /** * Sets the position for the motor in its encoder units. @@ -1208,7 +1040,8 @@ class Motor_Group { * \endcode * */ - std::int32_t set_zero_position(const double position) const; + std::int32_t set_zero_position(const double position, const std::uint8_t index = 0) const; + std::int32_t set_zero_position_all(const double position) const; /** * Sets the "absolute" zero position of the motor to its current position. @@ -1232,7 +1065,8 @@ class Motor_Group { * } * \endcode */ - std::int32_t tare_position(void) const; + std::int32_t tare_position(const std::uint8_t index = 0) const; + std::int32_t tare_position_all(void) const; /** * @brief Returns the number of objects @@ -1241,99 +1075,12 @@ class Motor_Group { */ std::int8_t size(void) const; - /** - * @brief Get the ports object - * - * @return std::vector - */ - std::vector get_ports(void) const; - - /** - * @brief Appends the other motor group reference to this motor group - * - */ - void operator+=(Motor_Group&); - - /** - * @brief Appends the other motor group reference to this motor group - * - */ - void append(Motor_Group&); - - /** - * @brief Removes the port (and it's reversed ) - * - * @param port - */ - void erase_port(std::int8_t port); - - /** - * This is the overload for the << operator for printing to streams - * - * Prints in format: - * Motor [port: (motor port), brake mode: (brake mode), current draw: (current draw), - * current limit: (current limit), direction: (direction), efficiency: (efficiency), - * encoder units: (encoder units), gearing: (gearing), is over temp: (over temp), - * position: (position), reversed: (reversed boolean), temperature: (temperature), - * torque: (torque), voltage: (voltage)] - */ - friend std::ostream& operator<<(std::ostream& os, pros::Motor_Group& motor); - ///@} - private: - std::vector _ports; - bool _reverse; - mutable pros::Mutex _motor_group_mutex; - pros::v5::Motor_Gear _gearset; - pros::v5::Motor_Units _encoder_units; - void push_motor_configuration(void) const; -}; - -///@} -class Motor : public Motor_Group, public Device { - public: - explicit Motor(const std::int8_t port); - - explicit Motor(const std::int8_t port, const pros::v5::Motor_Gears gearset, const bool reverse, - const pros::v5::Motor_Units encoder_units); - - explicit Motor(const std::int8_t port, const pros::v5::Motor_Gears gearset, const bool reverse); - - explicit Motor(const std::int8_t port, const pros::v5::Motor_Gears gearset); - - explicit Motor(const std::int8_t port, const bool reverse); + std::int8_t get_port(const std::uint8_t index = 0) const; DeviceType get_type() const; - using Motor_Group::operator=; - private: - using Motor_Group::operator+=; - using Motor_Group::append; - using Motor_Group::erase_port; - using Motor_Group::every_is_over_current; - using Motor_Group::every_is_over_temp; - using Motor_Group::every_is_reversed; - using Motor_Group::get_every_actual_velocity; - using Motor_Group::get_every_brake_mode; - using Motor_Group::get_every_current_draw; - using Motor_Group::get_every_current_limit; - using Motor_Group::get_every_direction; - using Motor_Group::get_every_efficiency; - using Motor_Group::get_every_encoder_units; - using Motor_Group::get_every_faults; - using Motor_Group::get_every_flags; - using Motor_Group::get_every_gearing; - using Motor_Group::get_every_port; - using Motor_Group::get_every_position; - using Motor_Group::get_every_power; - using Motor_Group::get_every_raw_position; - using Motor_Group::get_every_target_position; - using Motor_Group::get_every_target_velocity; - using Motor_Group::get_every_temperature; - using Motor_Group::get_every_torque; - using Motor_Group::get_every_voltage; - using Motor_Group::get_every_voltage_limit; - using Motor_Group::get_ports; + std::int8_t _port; }; namespace literals { const pros::Motor operator"" _mtr(const unsigned long long int m); diff --git a/src/devices/vdml_motorgroup.cpp b/src/devices/vdml_motorgroup.cpp new file mode 100644 index 000000000..a03ce68b8 --- /dev/null +++ b/src/devices/vdml_motorgroup.cpp @@ -0,0 +1,658 @@ +/** + * \file devices/vdml_motors.cpp + * + * Contains functions for interacting with the V5 Motors. + * + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "kapi.h" +#include "pros/motor_group.hpp" +#include "pros/motors.hpp" + +namespace pros { +inline namespace v5 { +using namespace pros::c; +#define empty_MotorGroup_check(error) \ + if (_ports.size() <= 0) { \ + errno = EDOM; \ + return error; \ + } +#define MotorGroup_index_check(error, index) \ + if (_ports.size() <= index || index < 0) { \ + errno = EOVERFLOW; \ + return error; \ + } + +#define empty_MotorGroup_check_vector(error, vector) \ + if (_ports.size() <= 0) { \ + errno = EDOM; \ + vector.emplace_back(error); \ + return vector; \ + } + +MotorGroup::MotorGroup(const std::initializer_list ports, + const pros::v5::Motor_Gears gearset, + const pros::v5::Motor_Units encoder_units) + : _ports(ports) { + set_gearing(gearset); + set_encoder_units(encoder_units); +} + +MotorGroup::MotorGroup(const std::vector& ports, + const pros::v5::Motor_Gears gearset, + const pros::v5::Motor_Units encoder_units) + : _ports(ports) { + set_gearing(gearset); + set_encoder_units(encoder_units); +} + +std::int32_t MotorGroup::operator=(std::int32_t voltage) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_move(*it, voltage); + } + return motor_move(_ports[0], voltage); +} + +std::int32_t MotorGroup::move(std::int32_t voltage) const { + empty_MotorGroup_check(PROS_ERR); + + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_move(*it, voltage); + } + return motor_move(_ports[0], voltage); +} + +std::int32_t MotorGroup::move_absolute(const double position, const std::int32_t velocity) const { + empty_MotorGroup_check(PROS_ERR); + + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_move_absolute(*it, position, velocity); + } + return motor_move_absolute(_ports[0], position, velocity); +} + +std::int32_t MotorGroup::move_relative(const double position, const std::int32_t velocity) const { + empty_MotorGroup_check(PROS_ERR); + + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_move_relative(*it, position, velocity); + } + return motor_move_relative(_ports[0], position, velocity); +} + +std::int32_t MotorGroup::move_velocity(const std::int32_t velocity) const { + empty_MotorGroup_check(PROS_ERR); + + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_move_velocity(*it, velocity); + } + return motor_move_velocity(_ports[0], velocity); +} + +std::int32_t MotorGroup::move_voltage(const std::int32_t voltage) const { + empty_MotorGroup_check(PROS_ERR); + + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_move_voltage(*it, voltage); + } + return motor_move_voltage(_ports[0], voltage); +} + +std::int32_t MotorGroup::brake(void) const { + empty_MotorGroup_check(PROS_ERR); + + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_brake(*it); + } + return motor_brake(_ports[0]); +} + +std::int32_t MotorGroup::modify_profiled_velocity(const std::int32_t velocity) const { + empty_MotorGroup_check(PROS_ERR); + + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_modify_profiled_velocity(*it, velocity); + } + return motor_modify_profiled_velocity(_ports[0], velocity); +} + +double MotorGroup::get_actual_velocity(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR_F); + MotorGroup_index_check(PROS_ERR_F, index); + + return motor_get_actual_velocity(_ports[index]); +} +std::vector MotorGroup::get_actual_velocity_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR_F, return_vector); + + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_actual_velocity(*it)); + } + return return_vector; +} + +pros::v5::Motor_Brake MotorGroup::get_brake_mode(const std::uint8_t index) const { + empty_MotorGroup_check(pros::v5::Motor_Brake::invalid); + MotorGroup_index_check(pros::v5::Motor_Brake::invalid, index); + + return static_cast(motor_get_brake_mode(_ports[index])); +} + +std::vector MotorGroup::get_brake_mode_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(pros::v5::Motor_Brake::invalid, return_vector); + + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(static_cast(motor_get_brake_mode(*it))); + } + return return_vector; +} + +std::int32_t MotorGroup::get_current_draw(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + + return motor_get_current_draw(_ports[index]); +} +std::vector MotorGroup::get_current_draw_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_current_draw(*it)); + } + return return_vector; +} + +std::int32_t MotorGroup::get_current_limit(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + + return motor_get_current_limit(_ports[index]); +} + +std::vector MotorGroup::get_current_limit_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_current_limit(*it)); + } + return return_vector; +} + +std::int32_t MotorGroup::is_over_current(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_is_over_current(_ports[index]); +} + +std::vector MotorGroup::is_over_current_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_is_over_current(*it)); + } + return return_vector; +} + +std::int32_t MotorGroup::get_direction(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_get_direction(_ports[index]); +} + +std::vector MotorGroup::get_direction_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_direction(*it)); + } + return return_vector; +} + +double MotorGroup::get_efficiency(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR_F); + MotorGroup_index_check(PROS_ERR_F, index); + return motor_get_efficiency(_ports[index]); +} + +std::vector MotorGroup::get_efficiency_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR_F, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_efficiency(*it)); + } + return return_vector; +} + +pros::v5::Motor_Units MotorGroup::get_encoder_units(const std::uint8_t index) const { + empty_MotorGroup_check(pros::v5::Motor_Units::invalid); + MotorGroup_index_check(pros::v5::Motor_Units::invalid, index); + return static_cast(motor_get_encoder_units(_ports[index])); +} + +std::vector MotorGroup::get_encoder_units_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(pros::v5::Motor_Units::invalid, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(static_cast(motor_get_encoder_units(*it))); + } + return return_vector; +} + +std::uint32_t MotorGroup::get_faults(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_get_faults(_ports[index]); +} + +std::vector MotorGroup::get_faults_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_faults(*it)); + } + return return_vector; +} + +std::uint32_t MotorGroup::get_flags(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_get_flags(_ports[index]); +} + +std::vector MotorGroup::get_flags_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_flags(*it)); + } + return return_vector; +} + +pros::v5::Motor_Gears MotorGroup::get_gearing(const std::uint8_t index) const { + empty_MotorGroup_check(pros::v5::Motor_Gears::invalid); + MotorGroup_index_check(pros::v5::Motor_Gears::invalid, index); + return static_cast(motor_get_gearing(_ports[index])); +} + +std::vector MotorGroup::get_gearing_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(pros::v5::Motor_Gears::invalid, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(static_cast(motor_get_gearing(*it))); + } + return return_vector; +} + +std::int32_t MotorGroup::get_raw_position(std::uint32_t* const timestamp, std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_get_raw_position(_ports[index], timestamp); +} + +std::vector MotorGroup::get_raw_position_all(std::uint32_t* const timestamp) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_raw_position(*it, timestamp)); + } + return return_vector; +} + +std::int32_t MotorGroup::is_over_temp(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_is_over_temp(_ports[index]); +} + +std::vector MotorGroup::is_over_temp_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_is_over_temp(*it)); + } + return return_vector; +} + +double MotorGroup::get_position(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR_F); + MotorGroup_index_check(PROS_ERR_F, index); + return motor_get_position(_ports[index]); +} + +std::vector MotorGroup::get_position_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR_F, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_position(*it)); + } + return return_vector; +} + +double MotorGroup::get_power(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR_F); + MotorGroup_index_check(PROS_ERR_F, index); + return motor_get_power(_ports[index]); +} + +std::vector MotorGroup::get_power_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR_F, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_power(*it)); + } + return return_vector; +} + +std::int32_t MotorGroup::is_reversed(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_is_reversed(index); +} + +std::vector MotorGroup::is_reversed_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_is_reversed(*it)); + } + return return_vector; +} + +double MotorGroup::get_temperature(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR_F); + MotorGroup_index_check(PROS_ERR_F, index); + return motor_get_temperature(_ports[index]); +} + +std::vector MotorGroup::get_temperature_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR_F, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_temperature(*it)); + } + return return_vector; +} + +double MotorGroup::get_target_position(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR_F); + MotorGroup_index_check(PROS_ERR_F, index); + return motor_get_target_position(_ports[index]); +} + +std::vector MotorGroup::get_target_position_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR_F, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_target_position(*it)); + } + return return_vector; +} + +double MotorGroup::get_torque(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR_F); + MotorGroup_index_check(PROS_ERR_F, index); + return motor_get_torque(_ports[index]); +} + +std::vector MotorGroup::get_torque_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR_F, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_torque(*it)); + } + return return_vector; +} + +std::int32_t MotorGroup::get_target_velocity(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_get_target_velocity(_ports[index]); +} + +std::vector MotorGroup::get_target_velocity_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_target_velocity(*it)); + } + return return_vector; +} + +std::int32_t MotorGroup::get_voltage(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_get_voltage(_ports[index]); +} +std::vector MotorGroup::get_voltage_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_voltage(*it)); + } + return return_vector; +} + +std::int32_t MotorGroup::get_voltage_limit(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_get_voltage_limit(_ports[index]); +} + +std::vector MotorGroup::get_voltage_limit_all(void) const { + std::vector return_vector; + empty_MotorGroup_check_vector(PROS_ERR, return_vector); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + return_vector.emplace_back(motor_get_voltage_limit(*it)); + } + return return_vector; +} + +std::int8_t MotorGroup::get_port(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR_BYTE); + MotorGroup_index_check(PROS_ERR_BYTE, index); + return _ports[index]; +} + +std::vector MotorGroup::get_port_all(void) const { + return _ports; +} + +std::int32_t MotorGroup::tare_position(const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_tare_position(_ports[index]); +} + +std::int32_t MotorGroup::tare_position_all(void) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_tare_position(*it); + } + return motor_tare_position(_ports[0]); +} + +std::int32_t MotorGroup::set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_brake_mode(*it, mode); + } + return motor_set_brake_mode(_ports[index], mode); +} + +std::int32_t MotorGroup::set_brake_mode(const pros::v5::Motor_Brake mode, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + + return motor_set_brake_mode(_ports[index], static_cast(mode)); +} + +std::int32_t MotorGroup::set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_brake_mode(*it, mode); + } + return motor_set_brake_mode(_ports[0], mode); +} + +std::int32_t MotorGroup::set_brake_mode_all(const pros::v5::Motor_Brake mode) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_brake_mode(*it, static_cast(mode)); + } + return motor_set_brake_mode(_ports[0], static_cast(mode)); +} +std::int32_t MotorGroup::set_current_limit(const std::int32_t limit, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_set_current_limit(_ports[index], limit); +} +std::int32_t MotorGroup::set_current_limit_all(const std::int32_t limit) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_current_limit(*it, limit); + } + return motor_set_current_limit(_ports[0], limit); +} +std::int32_t MotorGroup::set_encoder_units_all(const pros::motor_encoder_units_e_t units) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_encoder_units(*it, units); + } + return motor_set_encoder_units(_ports[0], units); +} + +std::int32_t MotorGroup::set_encoder_units_all(const pros::v5::Motor_Units units) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_encoder_units(*it, static_cast(units)); + } + return motor_set_encoder_units(_ports[0], static_cast(units)); +} +std::int32_t MotorGroup::set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_set_encoder_units(_ports[index], units); +} + +std::int32_t MotorGroup::set_encoder_units(const pros::v5::Motor_Units units, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_encoder_units(*it, static_cast(units)); + } + return motor_set_encoder_units(_ports[0], static_cast(units)); +} + +std::int32_t MotorGroup::set_gearing(const motor_gearset_e_t gearset, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_set_gearing(_ports[index], gearset); +} + +std::int32_t MotorGroup::set_gearing(const pros::v5::Motor_Gear gearset, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_set_gearing(_ports[index], (motor_gearset_e_t)gearset); +} + +std::int32_t MotorGroup::set_gearing_all(const motor_gearset_e_t gearset) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_gearing(*it, gearset); + } + return motor_set_gearing(_ports[0], gearset); +} + +std::int32_t MotorGroup::set_gearing_all(const pros::v5::Motor_Gear gearset) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_gearing(*it, (motor_gearset_e_t)gearset); + } + return motor_set_gearing(_ports[0], (motor_gearset_e_t)gearset); +} + +std::int32_t MotorGroup::set_zero_position(const double position, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_set_zero_position(_ports[index], position); +} +std::int32_t MotorGroup::set_zero_position_all(const double position) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_zero_position(*it, position); + } + return motor_set_zero_position(_ports[0], position); +} +std::int32_t MotorGroup::set_reversed(const bool reverse, const std::uint8_t index) { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + std::int8_t abs_port = std::abs(_ports[index]); + if (reverse) { + _ports[index] = -abs_port; + } else { + _ports[index] = abs_port; + } + return PROS_SUCCESS; +} +std::int32_t MotorGroup::set_reversed_all(const bool reverse) { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin(); it < _ports.end(); it++) { + std::int8_t abs_port = std::abs(_ports[*it]); + if (reverse) { + _ports[*it] = -abs_port; + } else { + _ports[*it] = abs_port; + } + } + return PROS_SUCCESS; +} +std::int32_t MotorGroup::set_voltage_limit(const std::int32_t limit, const std::uint8_t index) const { + empty_MotorGroup_check(PROS_ERR); + MotorGroup_index_check(PROS_ERR, index); + return motor_set_voltage_limit(_ports[index], limit); +} +std::int32_t MotorGroup::set_voltage_limit_all(const std::int32_t limit) const { + empty_MotorGroup_check(PROS_ERR); + for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { + motor_set_voltage_limit(*it, limit); + } + return motor_set_voltage_limit(_ports[0], limit); +} + +std::int8_t MotorGroup::size() const { + return _ports.size(); +} + +void MotorGroup::operator+=(MotorGroup& other) { + for (auto it = other._ports.begin(); it < other._ports.end(); it++) { + _ports.emplace_back(*it); + } +} + +void MotorGroup::append(MotorGroup& other) { + (*this) += other; +} + +void MotorGroup::erase_port(std::int8_t port) { + auto it = _ports.begin(); + while (it < _ports.end()) { + if (std::abs(*it) == std::abs(port)) { + _ports.erase(it); + } else { + it++; + } + } +} +} // namespace v5 +} // namespace pros \ No newline at end of file diff --git a/src/devices/vdml_motors.c b/src/devices/vdml_motors.c index f7efd7b87..340ef16be 100644 --- a/src/devices/vdml_motors.c +++ b/src/devices/vdml_motors.c @@ -15,6 +15,7 @@ #include #include "kapi.h" +#include "pros/colors.h" #include "pros/motors.h" #include "v5_api.h" #include "vdml/registry.h" @@ -23,17 +24,20 @@ #define MOTOR_MOVE_RANGE 127 #define MOTOR_VOLTAGE_RANGE 12000 - // Movement functions int32_t motor_move(int8_t port, int32_t voltage) { - port = abs(port); if (voltage > 127) { voltage = 127; } else if (voltage < -127) { voltage = -127; } + if (port < 0) { + voltage = -voltage; + } + + port = abs(port); // Remap the input voltage range to the motor voltage // scale to [-127, 127] -> [-12000, 12000] int32_t command = (((voltage + MOTOR_MOVE_RANGE) * (MOTOR_VOLTAGE_RANGE)) / (MOTOR_MOVE_RANGE)); @@ -42,43 +46,47 @@ int32_t motor_move(int8_t port, int32_t voltage) { } int32_t motor_brake(int8_t port) { - port = abs(port); return motor_move_velocity(port, 0); } -int32_t motor_move_absolute(int8_t port, const double position, const int32_t velocity) { - port = abs(port); - claim_port_i(port - 1, E_DEVICE_MOTOR); +int32_t motor_move_absolute(int8_t port, const double position, int32_t velocity) { + uint8_t abs_port = abs(port); + claim_port_i(abs_port - 1, E_DEVICE_MOTOR); + if (port < 0) velocity = -velocity; vexDeviceMotorAbsoluteTargetSet(device->device_info, position, velocity); - return_port(port - 1, PROS_SUCCESS); + return_port(abs_port - 1, PROS_SUCCESS); } -int32_t motor_move_relative(int8_t port, const double position, const int32_t velocity) { - port = abs(port); - claim_port_i(port - 1, E_DEVICE_MOTOR); +int32_t motor_move_relative(int8_t port, const double position, int32_t velocity) { + uint8_t abs_port = abs(port); + claim_port_i(abs_port - 1, E_DEVICE_MOTOR); + if (port < 0) velocity = -velocity; vexDeviceMotorRelativeTargetSet(device->device_info, position, velocity); - return_port(port - 1, PROS_SUCCESS); + return_port(abs_port - 1, PROS_SUCCESS); } -int32_t motor_move_velocity(int8_t port, const int32_t velocity) { - port = abs(port); - claim_port_i(port - 1, E_DEVICE_MOTOR); +int32_t motor_move_velocity(int8_t port, int32_t velocity) { + uint8_t abs_port = abs(port); + claim_port_i(abs_port - 1, E_DEVICE_MOTOR); + if (port < 0) velocity = -velocity; vexDeviceMotorVelocitySet(device->device_info, velocity); - return_port(port - 1, PROS_SUCCESS); + return_port(abs_port - 1, PROS_SUCCESS); } -int32_t motor_move_voltage(int8_t port, const int32_t voltage) { - port = abs(port); - claim_port_i(port - 1, E_DEVICE_MOTOR); +int32_t motor_move_voltage(int8_t port, int32_t voltage) { + uint8_t abs_port = abs(port); + claim_port_i(abs_port - 1, E_DEVICE_MOTOR); + if (port < 0) voltage = -voltage; vexDeviceMotorVoltageSet(device->device_info, voltage); - return_port(port - 1, PROS_SUCCESS); + return_port(abs_port - 1, PROS_SUCCESS); } -int32_t motor_modify_profiled_velocity(int8_t port, const int32_t velocity) { - port = abs(port); - claim_port_i(port - 1, E_DEVICE_MOTOR); +int32_t motor_modify_profiled_velocity(int8_t port, int32_t velocity) { + uint8_t abs_port = abs(port); + claim_port_i(abs_port - 1, E_DEVICE_MOTOR); + if (port < 0) velocity = -velocity; vexDeviceMotorVelocityUpdate(device->device_info, velocity); - return_port(port - 1, PROS_SUCCESS); + return_port(abs_port - 1, PROS_SUCCESS); } double motor_get_target_position(int8_t port) { @@ -139,8 +147,6 @@ int32_t motor_is_over_temp(int8_t port) { return_port(port - 1, rtn); } - - uint32_t motor_get_faults(int8_t port) { port = abs(port); claim_port_i(port - 1, E_DEVICE_MOTOR); @@ -238,7 +244,7 @@ int32_t motor_set_gearing(int8_t port, const motor_gearset_e_t gearset) { port = abs(port); claim_port_i(port - 1, E_DEVICE_MOTOR); vexDeviceMotorGearingSet(device->device_info, (V5MotorGearset)gearset); - return_port(port - 1, PROS_SUCCESS); + return_port(port - 1, PROS_SUCCESS); } int32_t motor_set_reversed(int8_t port, const bool reverse) { diff --git a/src/devices/vdml_motors.cpp b/src/devices/vdml_motors.cpp index b75c706b3..fcd571c4f 100644 --- a/src/devices/vdml_motors.cpp +++ b/src/devices/vdml_motors.cpp @@ -17,751 +17,502 @@ namespace pros { inline namespace v5 { using namespace pros::c; -#define empty_motor_group_check(error) \ - if (_ports.size() <= 0) { \ - errno = EDOM; \ - return error; \ - } -#define motor_group_index_check(error, index) \ - if (_ports.size() <= index || index < 0) { \ - errno = EOVERFLOW; \ - return error; \ - } - -#define empty_motor_group_check_vector(error, vector) \ - if (_ports.size() <= 0) { \ - errno = EDOM; \ - vector.emplace_back(error); \ - return vector; \ - } - -Motor_Group::Motor_Group(const std::initializer_list ports, const pros::v5::Motor_Gears gearset, - const bool reverse, const pros::v5::Motor_Units encoder_units) - : _ports(ports) { +Motor::Motor(const std::int8_t port, const pros::v5::Motor_Gears gearset, const pros::v5::Motor_Units encoder_units) + : Device(port), _port(port) { set_gearing(gearset); - set_reversed(reverse); set_encoder_units(encoder_units); } -Motor_Group::Motor_Group(const std::initializer_list ports, const pros::v5::Motor_Gears gearset, - const bool reverse) - : _ports(ports) { - set_gearing(gearset); - set_reversed(reverse); -} - -Motor_Group::Motor_Group(const std::initializer_list ports, const pros::v5::Motor_Gears gearset) - : _ports(ports) { - set_gearing(gearset); +std::int32_t Motor::operator=(std::int32_t voltage) const { + return motor_move(_port, voltage); } -Motor_Group::Motor_Group(const std::initializer_list ports, const bool reverse) : _ports(ports) { - set_reversed(reverse); -} +std::int32_t Motor::move(std::int32_t voltage) const { + return motor_move(_port, voltage); -Motor_Group::Motor_Group(const std::initializer_list ports) : _ports(ports) {} -Motor_Group::Motor_Group(const std::vector ports, const pros::v5::Motor_Gears gearset, const bool reverse, - const pros::v5::Motor_Units encoder_units) - : _ports(ports) { - set_gearing(gearset); - set_reversed(reverse); - set_encoder_units(encoder_units); } -Motor_Group::Motor_Group(const std::vector ports, const pros::v5::Motor_Gears gearset, const bool reverse) - : _ports(ports) { - set_gearing(gearset); - set_reversed(reverse); +std::int32_t Motor::move_absolute(const double position, const std::int32_t velocity) const { + return motor_move_absolute(_port, position, velocity); } -Motor_Group::Motor_Group(const std::vector ports, const pros::v5::Motor_Gears gearset) : _ports(ports) { - set_gearing(gearset); +std::int32_t Motor::move_relative(const double position, const std::int32_t velocity) const { + return motor_move_relative(_port, position, velocity); } -Motor_Group::Motor_Group(const std::vector ports, const bool reverse) : _ports(ports) { - set_reversed(reverse); +std::int32_t Motor::move_velocity(const std::int32_t velocity) const { + return motor_move_velocity(_port, velocity); } -Motor_Group::Motor_Group(const std::vector ports) : _ports(ports) {} - -std::int32_t Motor_Group::operator=(std::int32_t voltage) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_move(*it, voltage); - } - return motor_move(_ports[0], voltage); +std::int32_t Motor::move_voltage(const std::int32_t voltage) const { + return motor_move_voltage(_port, voltage); } -std::int32_t Motor_Group::move(std::int32_t voltage) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_move(*it, voltage); - } - return motor_move(_ports[0], voltage); +std::int32_t Motor::brake(void) const { + return motor_brake(_port); } -std::int32_t Motor_Group::move_absolute(const double position, const std::int32_t velocity) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_move_absolute(*it, position, velocity); - } - return motor_move_absolute(_ports[0], position, velocity); +std::int32_t Motor::modify_profiled_velocity(const std::int32_t velocity) const { + return motor_modify_profiled_velocity(_port, velocity); } -std::int32_t Motor_Group::move_relative(const double position, const std::int32_t velocity) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_move_relative(*it, position, velocity); +double Motor::get_actual_velocity(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR_F; } - return motor_move_relative(_ports[0], position, velocity); + return motor_get_actual_velocity(_port); } - -std::int32_t Motor_Group::move_velocity(const std::int32_t velocity) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_move_velocity(*it, velocity); - } - return motor_move_velocity(_ports[0], velocity); -} - -std::int32_t Motor_Group::move_voltage(const std::int32_t voltage) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_move_voltage(*it, voltage); - } - return motor_move_voltage(_ports[0], voltage); -} - -std::int32_t Motor_Group::brake(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_brake(*it); - } - return motor_brake(_ports[0]); -} - -std::int32_t Motor_Group::modify_profiled_velocity(const std::int32_t velocity) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_modify_profiled_velocity(*it, velocity); - } - return motor_modify_profiled_velocity(_ports[0], velocity); -} - -double Motor_Group::get_actual_velocity(void) const { - empty_motor_group_check(PROS_ERR_F); - push_motor_configuration(); - return motor_get_actual_velocity(_ports[0]); -} - -double Motor_Group::get_actual_velocity(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR_F); - motor_group_index_check(PROS_ERR_F, index); - push_motor_configuration(); - return motor_get_actual_velocity(_ports[index]); -} -std::vector Motor_Group::get_every_actual_velocity(void) const { +std::vector Motor::get_actual_velocity_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR_F, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_actual_velocity(*it)); - } + return_vector.emplace_back(motor_get_actual_velocity(_port)); return return_vector; } -pros::v5::Motor_Brake Motor_Group::get_brake_mode(void) const { - empty_motor_group_check(pros::v5::Motor_Brake::invalid); - push_motor_configuration(); - return static_cast(motor_get_brake_mode(_ports[0])); -} -pros::v5::Motor_Brake Motor_Group::get_brake_mode(std::uint8_t index) const { - empty_motor_group_check(pros::v5::Motor_Brake::invalid); - motor_group_index_check(pros::v5::Motor_Brake::invalid, index); - push_motor_configuration(); - return static_cast(motor_get_brake_mode(_ports[index])); +pros::v5::Motor_Brake Motor::get_brake_mode(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return pros::v5::Motor_Brake::invalid; + } + return static_cast(motor_get_brake_mode(_port)); } -std::vector Motor_Group::get_every_brake_mode(void) const { +std::vector Motor::get_brake_mode_all() const { std::vector return_vector; - empty_motor_group_check_vector(pros::v5::Motor_Brake::invalid, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(static_cast(motor_get_brake_mode(*it))); - } + return_vector.emplace_back(static_cast(motor_get_brake_mode(_port))); return return_vector; } -std::int32_t Motor_Group::get_current_draw(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_current_draw(_ports[0]); -} -std::int32_t Motor_Group::get_current_draw(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_current_draw(_ports[index]); +std::int32_t Motor::get_current_draw(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_current_draw(_port); } -std::vector Motor_Group::get_every_current_draw(void) const { +std::vector Motor::get_current_draw_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_current_draw(*it)); - } + return_vector.emplace_back(motor_get_current_draw(_port)); return return_vector; } -std::int32_t Motor_Group::get_current_limit(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_current_limit(_ports[0]); -} -std::int32_t Motor_Group::get_current_limit(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_current_limit(_ports[index]); +std::int32_t Motor::get_current_limit(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_current_limit(_port); } -std::vector Motor_Group::get_every_current_limit(void) const { +std::vector Motor::get_current_limit_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_current_limit(*it)); - } + return_vector.emplace_back(motor_get_current_limit(_port)); return return_vector; } -std::int32_t Motor_Group::is_over_current(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_is_over_current(_ports[0]); -} -std::int32_t Motor_Group::is_over_current(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_is_over_current(_ports[index]); + +std::int32_t Motor::is_over_current(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_is_over_current(_port); } -std::vector Motor_Group::every_is_over_current(void) const { +std::vector Motor::is_over_current_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_is_over_current(*it)); - } + return_vector.emplace_back(motor_is_over_current(_port)); + return return_vector; } -std::int32_t Motor_Group::get_direction(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_direction(_ports[0]); -} -std::int32_t Motor_Group::get_direction(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_direction(_ports[index]); +std::int32_t Motor::get_direction(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_direction(_port); } -std::vector Motor_Group::get_every_direction(void) const { +std::vector Motor::get_direction_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_direction(*it)); - } + return_vector.emplace_back(motor_get_direction(_port)); return return_vector; } -double Motor_Group::get_efficiency(void) const { - empty_motor_group_check(PROS_ERR_F); - push_motor_configuration(); - return motor_get_efficiency(_ports[0]); -} -double Motor_Group::get_efficiency(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR_F); - motor_group_index_check(PROS_ERR_F, index); - push_motor_configuration(); - return motor_get_efficiency(_ports[index]); +double Motor::get_efficiency(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR_F; + } + return motor_get_efficiency(_port); } -std::vector Motor_Group::get_every_efficiency(void) const { +std::vector Motor::get_efficiency_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR_F, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_efficiency(*it)); - } + return_vector.emplace_back(motor_get_efficiency(_port)); return return_vector; } -pros::v5::Motor_Units Motor_Group::get_encoder_units(void) const { - return _encoder_units; -} -pros::v5::Motor_Units Motor_Group::get_encoder_units(std::uint8_t index) const { - empty_motor_group_check(pros::v5::Motor_Units::invalid); - motor_group_index_check(pros::v5::Motor_Units::invalid, index); - push_motor_configuration(); - return static_cast(motor_get_encoder_units(_ports[index])); +pros::v5::Motor_Units Motor::get_encoder_units(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return pros::v5::Motor_Units::invalid; + } + return static_cast(motor_get_encoder_units(_port)); } -std::vector Motor_Group::get_every_encoder_units(void) const { +std::vector Motor::get_encoder_units_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(pros::v5::Motor_Units::invalid, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(static_cast(motor_get_encoder_units(*it))); - } + return_vector.emplace_back(static_cast(motor_get_encoder_units(_port))); return return_vector; } -std::uint32_t Motor_Group::get_faults(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_faults(_ports[0]); -} -std::uint32_t Motor_Group::get_faults(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_faults(_ports[index]); +std::uint32_t Motor::get_faults(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_faults(_port); } -std::vector Motor_Group::get_every_faults(void) const { +std::vector Motor::get_faults_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_faults(*it)); - } + return_vector.emplace_back(motor_get_faults(_port)); return return_vector; } -std::uint32_t Motor_Group::get_flags(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_flags(_ports[0]); -} -std::uint32_t Motor_Group::get_flags(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_flags(_ports[index]); +std::uint32_t Motor::get_flags(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_flags(_port); } -std::vector Motor_Group::get_every_flags(void) const { +std::vector Motor::get_flags_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_flags(*it)); - } + return_vector.emplace_back(motor_get_flags(_port)); return return_vector; } -pros::v5::Motor_Gears Motor_Group::get_gearing(void) const { - return _gearset; -} - -pros::v5::Motor_Gears Motor_Group::get_gearing(std::uint8_t index) const { - empty_motor_group_check(pros::v5::Motor_Gears::invalid); - motor_group_index_check(pros::v5::Motor_Gears::invalid, index); - push_motor_configuration(); - return static_cast(motor_get_gearing(_ports[index])); +pros::v5::Motor_Gears Motor::get_gearing(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return pros::v5::Motor_Gears::invalid; + } + return static_cast(motor_get_gearing(_port)); } -std::vector Motor_Group::get_every_gearing(void) const { +std::vector Motor::get_gearing_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(pros::v5::Motor_Gears::invalid, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(static_cast(motor_get_gearing(*it))); - } + return_vector.emplace_back(static_cast(motor_get_gearing(_port))); return return_vector; } -std::int32_t Motor_Group::get_raw_position(std::uint32_t* const timestamp) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_raw_position(_ports[0], timestamp); -} -std::int32_t Motor_Group::get_raw_position(std::uint32_t* const timestamp, std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_raw_position(_ports[index], timestamp); +std::int32_t Motor::get_raw_position(std::uint32_t* const timestamp, std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_raw_position(_port, timestamp); } -std::vector Motor_Group::get_every_raw_position(std::uint32_t* const timestamp) const { +std::vector Motor::get_raw_position_all(std::uint32_t* const timestamp) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_raw_position(*it, timestamp)); - } + return_vector.emplace_back(motor_get_raw_position(_port, timestamp)); return return_vector; } -std::int32_t Motor_Group::is_over_temp(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_is_over_temp(_ports[0]); -} -std::int32_t Motor_Group::is_over_temp(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_is_over_temp(_ports[index]); + +std::int32_t Motor::is_over_temp(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_is_over_temp(_port); } -std::vector Motor_Group::every_is_over_temp(void) const { +std::vector Motor::is_over_temp_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_is_over_temp(*it)); - } + return_vector.emplace_back(motor_is_over_temp(_port)); return return_vector; } -double Motor_Group::get_position(void) const { - empty_motor_group_check(PROS_ERR_F); - push_motor_configuration(); - return motor_get_position(_ports[0]); -} -double Motor_Group::get_position(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR_F); - motor_group_index_check(PROS_ERR_F, index); - push_motor_configuration(); - return motor_get_position(_ports[index]); +double Motor::get_position(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR_F; + } + return motor_get_position(_port); } -std::vector Motor_Group::get_every_position(void) const { +std::vector Motor::get_position_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR_F, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_position(*it)); - } + return_vector.emplace_back(motor_get_position(_port)); return return_vector; } -double Motor_Group::get_power(void) const { - empty_motor_group_check(PROS_ERR_F); - push_motor_configuration(); - return motor_get_power(_ports[0]); -} - -double Motor_Group::get_power(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR_F); - motor_group_index_check(PROS_ERR_F, index); - push_motor_configuration(); - return motor_get_power(_ports[index]); +double Motor::get_power(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_power(_port); } -std::vector Motor_Group::get_every_power(void) const { +std::vector Motor::get_power_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR_F, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_power(*it)); - } + return_vector.emplace_back(motor_get_power(_port)); return return_vector; } -std::int32_t Motor_Group::is_reversed(void) const { - empty_motor_group_check(PROS_ERR); - return _reverse; -} -std::int32_t Motor_Group::is_reversed(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_is_reversed(index); +std::int32_t Motor::is_reversed(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return _port < 0; } -std::vector Motor_Group::every_is_reversed(void) const { +std::vector Motor::is_reversed_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_is_reversed(*it)); - } + return_vector.emplace_back(_port < 0); return return_vector; } -double Motor_Group::get_temperature(void) const { - empty_motor_group_check(PROS_ERR_F); - push_motor_configuration(); - return motor_get_temperature(_ports[0]); -} -double Motor_Group::get_temperature(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR_F); - motor_group_index_check(PROS_ERR_F, index); - push_motor_configuration(); - return motor_get_temperature(_ports[index]); +double Motor::get_temperature(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR_F; + } + return motor_get_temperature(_port); } -std::vector Motor_Group::get_every_temperature(void) const { +std::vector Motor::get_temperature_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR_F, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_temperature(*it)); - } + return_vector.emplace_back(motor_get_temperature(_port)); return return_vector; } -double Motor_Group::get_target_position(void) const { - empty_motor_group_check(PROS_ERR_F); - push_motor_configuration(); - return motor_get_target_position(_ports[0]); -} - -double Motor_Group::get_target_position(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR_F); - motor_group_index_check(PROS_ERR_F, index); - push_motor_configuration(); - return motor_get_target_position(_ports[index]); +double Motor::get_target_position(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_target_position(_port); } -std::vector Motor_Group::get_every_target_position(void) const { +std::vector Motor::get_target_position_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR_F, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_target_position(*it)); - } + return_vector.emplace_back(motor_get_target_position(_port)); return return_vector; } -double Motor_Group::get_torque(void) const { - empty_motor_group_check(PROS_ERR_F); - push_motor_configuration(); - return motor_get_torque(_ports[0]); -} -double Motor_Group::get_torque(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR_F); - motor_group_index_check(PROS_ERR_F, index); - push_motor_configuration(); - return motor_get_torque(_ports[index]); +double Motor::get_torque(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_torque(_port); } -std::vector Motor_Group::get_every_torque(void) const { +std::vector Motor::get_torque_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR_F, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_torque(*it)); - } + return_vector.emplace_back(motor_get_torque(_port)); return return_vector; } - -std::int32_t Motor_Group::get_target_velocity(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_target_velocity(_ports[0]); -} -std::int32_t Motor_Group::get_target_velocity(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_target_velocity(_ports[index]); +std::int32_t Motor::get_target_velocity(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_target_velocity(_port); } -std::vector Motor_Group::get_every_target_velocity(void) const { +std::vector Motor::get_target_velocity_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_target_velocity(*it)); - } + return_vector.emplace_back(motor_get_target_velocity(_port)); return return_vector; } -std::int32_t Motor_Group::get_voltage(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_voltage(_ports[0]); -} -std::int32_t Motor_Group::get_voltage(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_voltage(_ports[index]); +std::int32_t Motor::get_voltage(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_voltage(_port); } -std::vector Motor_Group::get_every_voltage(void) const { +std::vector Motor::get_voltage_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_voltage(*it)); - } + return_vector.emplace_back(motor_get_voltage(_port)); return return_vector; } -std::int32_t Motor_Group::get_voltage_limit(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - return motor_get_voltage_limit(_ports[0]); -} -std::int32_t Motor_Group::get_voltage_limit(std::uint8_t index) const { - empty_motor_group_check(PROS_ERR); - motor_group_index_check(PROS_ERR, index); - push_motor_configuration(); - return motor_get_voltage_limit(_ports[index]); + +std::int32_t Motor::get_voltage_limit(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; + } + return motor_get_voltage_limit(_port); } -std::vector Motor_Group::get_every_voltage_limit(void) const { +std::vector Motor::get_voltage_limit_all(void) const { std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back(motor_get_voltage_limit(*it)); - } + return_vector.emplace_back(motor_get_voltage_limit(_port)); return return_vector; } - -std::vector Motor_Group::get_every_port(void) const { - std::vector return_vector; - empty_motor_group_check_vector(PROS_ERR_BYTE, return_vector); - push_motor_configuration(); - for (auto it = _ports.begin(); it < _ports.end(); it++) { - return_vector.emplace_back((uint8_t)std::abs((*it))); +std::int8_t Motor::get_port(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR_BYTE; } + return _port; +} + +std::vector Motor::get_port_all(void) const { + std::vector return_vector; + return_vector.emplace_back(_port); return return_vector; } -std::int32_t Motor_Group::tare_position(void) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_tare_position(*it); +std::int32_t Motor::tare_position(const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_tare_position(_ports[0]); + return motor_tare_position(_port); } -std::int32_t Motor_Group::set_brake_mode(const pros::motor_brake_mode_e_t mode) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_brake_mode(*it, mode); +std::int32_t Motor::set_brake_mode(const pros::motor_brake_mode_e_t mode, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_brake_mode(_ports[0], mode); + return motor_set_brake_mode(_port, mode); } -std::int32_t Motor_Group::set_brake_mode(const pros::v5::Motor_Brake mode) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_brake_mode(*it, static_cast(mode)); +std::int32_t Motor::set_brake_mode(const pros::v5::Motor_Brake mode, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_brake_mode(_ports[0], static_cast(mode)); + return motor_set_brake_mode(_port, static_cast(mode)); } -std::int32_t Motor_Group::set_current_limit(const std::int32_t limit) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_current_limit(*it, limit); +std::int32_t Motor::set_current_limit(const std::int32_t limit, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_current_limit(_ports[0], limit); + return motor_set_current_limit(_port, limit); } -std::int32_t Motor_Group::set_encoder_units(const pros::motor_encoder_units_e_t units) { - empty_motor_group_check(PROS_ERR); - _encoder_units = static_cast(units); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_encoder_units(*it, units); +std::int32_t Motor::set_encoder_units(const pros::motor_encoder_units_e_t units, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_encoder_units(_ports[0], units); + return motor_set_encoder_units(_port, units); } -std::int32_t Motor_Group::set_encoder_units(const pros::v5::Motor_Units units) { - empty_motor_group_check(PROS_ERR); - _encoder_units = units; - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_encoder_units(*it, static_cast(units)); +std::int32_t Motor::set_encoder_units(const pros::v5::Motor_Units units, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_encoder_units(_ports[0], static_cast(units)); + return motor_set_encoder_units(_port, static_cast(units)); } -std::int32_t Motor_Group::set_gearing(const motor_gearset_e_t gearset) { - empty_motor_group_check(PROS_ERR); - _gearset = static_cast(gearset); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_gearing(*it, gearset); +std::int32_t Motor::set_gearing(const motor_gearset_e_t gearset, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_gearing(_ports[0], gearset); + return motor_set_gearing(_port, gearset); } -std::int32_t Motor_Group::set_gearing(const pros::v5::Motor_Gear gearset) { - empty_motor_group_check(PROS_ERR); - _gearset = gearset; - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_gearing(*it, (motor_gearset_e_t)gearset); +std::int32_t Motor::set_gearing(const pros::v5::Motor_Gear gearset, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_gearing(_ports[0], (motor_gearset_e_t)gearset); + return motor_set_gearing(_port, static_cast(gearset)); } -std::int32_t Motor_Group::set_zero_position(const double position) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_zero_position(*it, position); +std::int32_t Motor::set_zero_position(const double position, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_zero_position(_ports[0], position); + return motor_set_zero_position(_port, position); } -std::int32_t Motor_Group::set_reversed(const bool reverse) { - empty_motor_group_check(PROS_ERR); - _reverse = reverse; - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_reversed(*it, reverse ^ ((*it) < 0)); +std::int32_t Motor::set_reversed(const bool reverse, const std::uint8_t index) { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } + std::int8_t abs_port = std::abs(_port); + if (reverse) { + _port = -abs_port; + } else { + _port = abs_port; - return motor_set_reversed(_ports[0], reverse ^ (_ports[0] < 0)); + } + return PROS_SUCCESS; } -std::int32_t Motor_Group::set_voltage_limit(const std::int32_t limit) const { - empty_motor_group_check(PROS_ERR); - push_motor_configuration(); - for (auto it = _ports.begin() + 1; it < _ports.end(); it++) { - motor_set_voltage_limit(*it, limit); +std::int32_t Motor::set_voltage_limit(const std::int32_t limit, const std::uint8_t index) const { + if (index != 0) { + errno = EOVERFLOW; + return PROS_ERR; } - return motor_set_voltage_limit(_ports[0], limit); + return motor_set_voltage_limit(_port, limit); } -std::vector Motor_Group::get_ports() const { - return _ports; +std::int32_t Motor::tare_position_all(void) const { + return motor_tare_position(_port); } -std::int8_t Motor_Group::size() const { - return _ports.size(); +std::int32_t Motor::set_brake_mode_all(const pros::motor_brake_mode_e_t mode) const { + return motor_set_brake_mode(_port, mode); } -void Motor_Group::operator+=(Motor_Group& other) { - for (auto it = other._ports.begin(); it < other._ports.end(); it++) { - _ports.emplace_back(*it); - } +std::int32_t Motor::set_brake_mode_all(const pros::v5::Motor_Brake mode) const { + return motor_set_brake_mode(_port, static_cast(mode)); +} + +std::int32_t Motor::set_current_limit_all(const std::int32_t limit) const { + return motor_set_current_limit(_port, limit); +} + +std::int32_t Motor::set_encoder_units_all(const pros::motor_encoder_units_e_t units) const { + return motor_set_encoder_units(_port, units); +} + +std::int32_t Motor::set_encoder_units_all(const pros::v5::Motor_Units units) const { + return motor_set_encoder_units(_port, static_cast(units)); +} + +std::int32_t Motor::set_gearing_all(const motor_gearset_e_t gearset) const { + return motor_set_gearing(_port, gearset); +} + +std::int32_t Motor::set_gearing_all(const pros::v5::Motor_Gear gearset) const { + return motor_set_gearing(_port, static_cast(gearset)); } -void Motor_Group::append(Motor_Group& other) { - (*this) += other; +std::int32_t Motor::set_zero_position_all(const double position) const { + return motor_set_zero_position(_port, position); } -void Motor_Group::erase_port(std::int8_t port) { - auto it = _ports.begin(); - while (it < _ports.end()) { - if (std::abs(*it) == std::abs(port)) { - _ports.erase(it); - } else { - it++; - } +std::int32_t Motor::set_reversed_all(const bool reverse) { + std::int8_t abs_port = std::abs(_port); + if (reverse) { + _port = -abs_port; } + return PROS_SUCCESS; } +std::int32_t Motor::set_voltage_limit_all(const std::int32_t limit) const { + return motor_set_voltage_limit(_port, limit); +} + +std::int8_t Motor::size() const { + return 1; +} +DeviceType Motor::get_type() const { + return DeviceType::motor; +} std::ostream& operator<<(std::ostream& os, pros::Motor& motor) { os << "Motor ["; os << "port: " << motor.get_port(); @@ -782,41 +533,14 @@ std::ostream& operator<<(std::ostream& os, pros::Motor& motor) { return os; } -void Motor_Group::push_motor_configuration() const { - _motor_group_mutex.take(); - for (auto it = _ports.begin() + 0; it < _ports.end(); it++) { - motor_set_gearing(*it, (motor_gearset_e_t)_gearset); - motor_set_reversed(*it, _reverse ^ ((*it) < 0)); - motor_set_encoder_units(*it, (motor_encoder_units_e_t)_encoder_units); - } - _motor_group_mutex.give(); -} - -Motor::Motor(const std::int8_t port) : Motor_Group({port}), Device(port) {} - -Motor::Motor(const std::int8_t port, const pros::v5::Motor_Gears gearset, const bool reverse, - const pros::v5::Motor_Units encoder_units) - : Motor_Group({port}, gearset, reverse, encoder_units), Device(port) {} - -Motor::Motor(const std::int8_t port, const pros::v5::Motor_Gears gearset, const bool reverse) - : Motor_Group({port}, gearset, reverse), Device(port) {} - -Motor::Motor(const std::int8_t port, const pros::v5::Motor_Gears gearset) - : Motor_Group({port}, gearset), Device(port) {} - -Motor::Motor(const std::int8_t port, const bool reverse) : Motor_Group({port}, reverse), Device(port) {} - -DeviceType Motor::get_type() const { - return DeviceType::motor; -} } // namespace v5 namespace literals { const pros::Motor operator"" _mtr(const unsigned long long int m) { - return pros::Motor(m, false); + return pros::Motor(m); } const pros::Motor operator"" _rmtr(const unsigned long long int m) { - return pros::Motor(m, true); + return pros::Motor(-m); } } // namespace literals } // namespace pros