/* * 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/. */ #pragma once #include "okapi/api/device/motor/abstractMotor.hpp" #include #include #include #include namespace okapi { /** * Converts inches to millimeters. */ static constexpr double inchToMM = 25.4; /** * Converts millimeters to inches. */ static constexpr double mmToInch = 0.0393700787; /** * Converts degrees to radians. */ static constexpr double degreeToRadian = 0.01745329252; /** * Converts radians to degrees. */ static constexpr double radianToDegree = 57.2957795; /** * The ticks per rotation of the 393 IME with torque gearing. */ static constexpr double imeTorqueTPR = 627.2; /** * The ticks per rotation of the 393 IME with speed gearing. */ static constexpr std::int32_t imeSpeedTPR = 392; /** * The ticks per rotation of the 393 IME with turbo gearing. */ static constexpr double imeTurboTPR = 261.333; /** * The ticks per rotation of the 269 IME. */ static constexpr double ime269TPR = 240.448; /** * The ticks per rotation of the V5 motor with a red gearset. */ static constexpr std::int32_t imev5RedTPR = 1800; /** * The ticks per rotation of the V5 motor with a green gearset. */ static constexpr std::int32_t imev5GreenTPR = 900; /** * The ticks per rotation of the V5 motor with a blue gearset. */ static constexpr std::int32_t imev5BlueTPR = 300; /** * The ticks per rotation of the red quadrature encoders. */ static constexpr std::int32_t quadEncoderTPR = 360; /** * The value of pi. */ static constexpr double pi = 3.1415926535897932; /** * The value of pi divided by 2. */ static constexpr double pi2 = 1.5707963267948966; /** * The conventional value of gravity of Earth. */ static constexpr double gravity = 9.80665; /** * Same as PROS_ERR. */ static constexpr auto OKAPI_PROS_ERR = INT32_MAX; /** * Same as PROS_ERR_F. */ static constexpr auto OKAPI_PROS_ERR_F = INFINITY; /** * The maximum voltage that can be sent to V5 motors. */ static constexpr double v5MotorMaxVoltage = 12000; /** * The polling frequency of V5 motors in milliseconds. */ static constexpr std::int8_t motorUpdateRate = 10; /** * The polling frequency of the ADI ports in milliseconds. */ static constexpr std::int8_t adiUpdateRate = 10; /** * Integer power function. Computes `base^expo`. * * @param base The base. * @param expo The exponent. * @return `base^expo`. */ constexpr double ipow(const double base, const int expo) { return (expo == 0) ? 1 : expo == 1 ? base : expo > 1 ? ((expo & 1) ? base * ipow(base, expo - 1) : ipow(base, expo / 2) * ipow(base, expo / 2)) : 1 / ipow(base, -expo); } /** * Cuts out a range from the number. The new range of the input number will be * `(-inf, min]U[max, +inf)`. If value sits equally between `min` and `max`, `max` will be returned. * * @param value The number to bound. * @param min The lower bound of range. * @param max The upper bound of range. * @return The remapped value. */ constexpr double cutRange(const double value, const double min, const double max) { const double middle = max - ((max - min) / 2); if (value > min && value < middle) { return min; } else if (value <= max && value >= middle) { return max; } return value; } /** * Deadbands a range of the number. Returns the input value, or `0` if it is in the range `[min, * max]`. * * @param value The number to deadband. * @param min The lower bound of deadband. * @param max The upper bound of deadband. * @return The input value or `0` if it is in the range `[min, max]`. */ constexpr double deadband(const double value, const double min, const double max) { return std::clamp(value, min, max) == value ? 0 : value; } /** * Remap a value in the range `[oldMin, oldMax]` to the range `[newMin, newMax]`. * * @param value The value in the old range. * @param oldMin The old range lower bound. * @param oldMax The old range upper bound. * @param newMin The new range lower bound. * @param newMax The new range upper bound. * @return The input value in the new range `[newMin, newMax]`. */ constexpr double remapRange(const double value, const double oldMin, const double oldMax, const double newMin, const double newMax) { return (value - oldMin) * ((newMax - newMin) / (oldMax - oldMin)) + newMin; } /** * Converts an enum to its value type. * * @param e The enum value. * @return The corresponding value. */ template constexpr auto toUnderlyingType(const E e) noexcept { return static_cast>(e); } /** * Converts a bool to a sign. * * @param b The bool. * @return True corresponds to `1` and false corresponds to `-1`. */ constexpr auto boolToSign(const bool b) noexcept { return b ? 1 : -1; } /** * Computes `lhs mod rhs` using Euclidean division. C's `%` symbol computes the remainder, not * modulus. * * @param lhs The left-hand side. * @param rhs The right-hand side. * @return `lhs` mod `rhs`. */ constexpr long modulus(const long lhs, const long rhs) noexcept { return ((lhs % rhs) + rhs) % rhs; } /** * Converts a gearset to its TPR. * * @param igearset The gearset. * @return The corresponding TPR. */ constexpr std::int32_t gearsetToTPR(const AbstractMotor::gearset igearset) noexcept { switch (igearset) { case AbstractMotor::gearset::red: return imev5RedTPR; case AbstractMotor::gearset::green: return imev5GreenTPR; case AbstractMotor::gearset::blue: case AbstractMotor::gearset::invalid: default: return imev5BlueTPR; } } /** * Maps ADI port numbers/chars to numbers: * ``` * when (port) { * in ['a', 'h'] -> [1, 8] * in ['A', 'H'] -> [1, 8] * else -> [1, 8] * } * ``` * * @param port The ADI port number or char. * @return An equivalent ADI port number. */ constexpr std::int8_t transformADIPort(const std::int8_t port) { if (port >= 'a' && port <= 'h') { return port - ('a' - 1); } else if (port >= 'A' && port <= 'H') { return port - ('A' - 1); } else { return port; } } } // namespace okapi