diff --git a/EZ-Template@2.1.2.zip b/EZ-Template@2.1.2.zip deleted file mode 100644 index 074e3f3d..00000000 Binary files a/EZ-Template@2.1.2.zip and /dev/null differ diff --git a/EZ-Template@2.2.0.zip b/EZ-Template@2.2.0.zip new file mode 100644 index 00000000..542b90de Binary files /dev/null and b/EZ-Template@2.2.0.zip differ diff --git a/Makefile b/Makefile index 40f62961..6a6db3f6 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ EXCLUDE_COLD_LIBRARIES:= IS_LIBRARY:=1 # TODO: CHANGE THIS! LIBNAME:=EZ-Template -VERSION:=2.1.2 +VERSION:=2.2.0 # EXCLUDE_SRC_FROM_LIB= $(SRCDIR)/unpublishedfile.c # this line excludes opcontrol.c and similar files EXCLUDE_SRC_FROM_LIB+=$(foreach file, $(SRCDIR)/autons $(SRCDIR)/main,$(foreach cext,$(CEXTS),$(file).$(cext)) $(foreach cxxext,$(CXXEXTS),$(file).$(cxxext))) diff --git a/README.md b/README.md index b05d6323..9bcde555 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ permalink: / Simple plug-and-play PROS template that handles drive base functions for VEX robots. -[EZ-Template Version](https://github.com/EZ-Robotics/EZ-Template): 2.1.1 +[EZ-Template Version](https://github.com/EZ-Robotics/EZ-Template): 2.2.0 [Autonomous routines that used EZ-Template](https://photos.app.goo.gl/yRwuvmq7hDoM4f6EA) diff --git a/common.mk b/common.mk index 84f7e219..10ab5d38 100644 --- a/common.mk +++ b/common.mk @@ -201,7 +201,7 @@ library: $(LIBAR) .PHONY: template template: clean-template $(LIBAR) - $Dprosv5 c create-template . $(LIBNAME) $(VERSION) $(foreach file,$(TEMPLATE_FILES) $(LIBAR),--system "$(file)") --target v5 $(CREATE_TEMPLATE_FLAGS) + $Dpros c create-template . $(LIBNAME) $(VERSION) $(foreach file,$(TEMPLATE_FILES) $(LIBAR),--system "$(file)") --target v5 $(CREATE_TEMPLATE_FLAGS) endif # if project is a library source, compile the archive and link output.elf against the archive rather than source objects @@ -280,7 +280,7 @@ $(VV)mkdir -p $(dir $(LDTIMEOBJ)) @# The shell command $$(($$(date +%s)+($$(date +%-z)/100*3600))) fetches the current @# unix timestamp, and then adds the UTC timezone offset to account for time zones. -$(call test_output_2,Adding timestamp ,echo 'const int _PROS_COMPILE_TIMESTAMP_INT = $(shell echo $$(($$(date +%s)+($$(date +%-z)/100*3600)))); char const * const _PROS_COMPILE_TIMESTAMP = __DATE__ " " __TIME__; char const * const _PROS_COMPILE_DIRECTORY = "$(shell pwd | tail -c 23)";' | $(CC) -c -x c $(CFLAGS) $(EXTRA_CFLAGS) -o $(LDTIMEOBJ) -,$(OK_STRING)) +$(call test_output_2,Adding timestamp ,echo 'const int _PROS_COMPILE_TIMESTAMP_INT = $(shell echo $$(($$(date +%s)+($$(date +%-z)/100*3600)))); char const * const _PROS_COMPILE_TIMESTAMP = __DATE__ " " __TIME__; char const * const _PROS_COMPILE_DIRECTORY = "$(wildcard $(shell pwd | tail -c 23))";' | $(CC) -c -x c $(CFLAGS) $(EXTRA_CFLAGS) -o $(LDTIMEOBJ) -,$(OK_STRING)) endef # these rules are for build-compile-commands, which just print out sysroot information diff --git a/firmware/libpros.a b/firmware/libpros.a index db5ad452..05399901 100644 Binary files a/firmware/libpros.a and b/firmware/libpros.a differ diff --git a/firmware/okapilib.a b/firmware/okapilib.a index 3b5174da..ae1c4df5 100644 Binary files a/firmware/okapilib.a and b/firmware/okapilib.a differ diff --git a/firmware/squiggles.mk b/firmware/squiggles.mk new file mode 100644 index 00000000..f970674a --- /dev/null +++ b/firmware/squiggles.mk @@ -0,0 +1 @@ +INCLUDE+=-iquote"$(ROOT)/include/okapi/squiggles" diff --git a/include/api.h b/include/api.h index 718030d1..7e923199 100644 --- a/include/api.h +++ b/include/api.h @@ -8,7 +8,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public @@ -40,9 +40,9 @@ #endif /* __cplusplus */ #define PROS_VERSION_MAJOR 3 -#define PROS_VERSION_MINOR 7 -#define PROS_VERSION_PATCH 3 -#define PROS_VERSION_STRING "3.7.3" +#define PROS_VERSION_MINOR 8 +#define PROS_VERSION_PATCH 0 +#define PROS_VERSION_STRING "3.8.0" #include "pros/adi.h" #include "pros/colors.h" diff --git a/include/okapi/api.hpp b/include/okapi/api.hpp index 57e73738..2c403e06 100644 --- a/include/okapi/api.hpp +++ b/include/okapi/api.hpp @@ -121,12 +121,14 @@ #include "okapi/api/units/QTime.hpp" #include "okapi/api/units/QTorque.hpp" #include "okapi/api/units/QVolume.hpp" +#include "okapi/api/units/RQuantityName.hpp" #include "okapi/api/util/abstractRate.hpp" #include "okapi/api/util/abstractTimer.hpp" #include "okapi/api/util/mathUtil.hpp" #include "okapi/api/util/supplier.hpp" #include "okapi/api/util/timeUtil.hpp" +#include "okapi/impl/util/configurableTimeUtilFactory.hpp" #include "okapi/impl/util/rate.hpp" #include "okapi/impl/util/timeUtilFactory.hpp" #include "okapi/impl/util/timer.hpp" diff --git a/include/okapi/api/chassis/controller/defaultOdomChassisController.hpp b/include/okapi/api/chassis/controller/defaultOdomChassisController.hpp index 91bbeb8d..f8fe52e8 100644 --- a/include/okapi/api/chassis/controller/defaultOdomChassisController.hpp +++ b/include/okapi/api/chassis/controller/defaultOdomChassisController.hpp @@ -99,7 +99,10 @@ class DefaultOdomChassisController : public OdomChassisController { void moveRawAsync(double itarget) override; /** - * This delegates to the input ChassisController. + * Turns chassis to desired angle (turns in the direction of smallest angle) + * (ex. If current angle is 0 and target is 270, the chassis will turn -90 degrees) + * + * @param idegTarget target angle */ void turnAngle(QAngle idegTarget) override; @@ -109,7 +112,10 @@ class DefaultOdomChassisController : public OdomChassisController { void turnRaw(double idegTarget) override; /** - * This delegates to the input ChassisController. + * Turns chassis to desired angle (turns in the direction of smallest angle) + * (ex. If current angle is 0 and target is 270, the chassis will turn -90 degrees) + * + * @param idegTarget target angle */ void turnAngleAsync(QAngle idegTarget) override; diff --git a/include/okapi/api/chassis/model/chassisModel.hpp b/include/okapi/api/chassis/model/chassisModel.hpp index efe01dbe..19687598 100644 --- a/include/okapi/api/chassis/model/chassisModel.hpp +++ b/include/okapi/api/chassis/model/chassisModel.hpp @@ -83,6 +83,18 @@ class ChassisModel : public ReadOnlyChassisModel { */ virtual void arcade(double iforwardSpeed, double iyaw, double ithreshold = 0) = 0; + /** + * Drive the robot with a curvature drive layout. The robot drives in constant radius turns + * where you control the curvature (inverse of radius) you drive in. This is advantageous + * because the forward speed will not affect the rate of turning. The algorithm switches to + * arcade if the forward speed is 0. Uses voltage mode. + * + * @param iforwardSpeed speed in the forward direction + * @param icurvature curvature (inverse of radius) to drive in + * @param ithreshold deadband on joystick values + */ + virtual void curvature(double iforwardSpeed, double icurvature, double ithreshold = 0) = 0; + /** * Power the left side motors. Uses velocity mode. * diff --git a/include/okapi/api/chassis/model/hDriveModel.hpp b/include/okapi/api/chassis/model/hDriveModel.hpp index 4224bf26..5afb95fc 100644 --- a/include/okapi/api/chassis/model/hDriveModel.hpp +++ b/include/okapi/api/chassis/model/hDriveModel.hpp @@ -100,6 +100,18 @@ class HDriveModel : public ChassisModel { */ void arcade(double iforwardSpeed, double iyaw, double ithreshold = 0) override; + /** + * Drive the robot with a curvature drive layout. The robot drives in constant radius turns + * where you control the curvature (inverse of radius) you drive in. This is advantageous + * because the forward speed will not affect the rate of turning. The algorithm switches to + * arcade if the forward speed is 0. Uses voltage mode. Sets the middle motor to zero velocity. + * + * @param iforwardSpeed speed in the forward direction + * @param icurvature curvature (inverse of radius) to drive in + * @param ithreshold deadband on joystick values + */ + void curvature(double iforwardSpeed, double icurvature, double ithreshold = 0) override; + /** * Drive the robot with an arcade drive layout. Uses voltage mode. * @@ -111,6 +123,17 @@ class HDriveModel : public ChassisModel { virtual void hArcade(double irightSpeed, double iforwardSpeed, double iyaw, double ithreshold = 0); + /** + * Drive the robot with an curvature drive layout. Uses voltage mode. + * + * @param irightSpeed speed to the right + * @param iforwardSpeed speed in the forward direction + * @param icurvature curvature (inverse of radius) to drive in + * @param ithreshold deadband on joystick values + */ + virtual void + hCurvature(double irightSpeed, double iforwardSpeed, double icurvature, double ithreshold = 0); + /** * Power the left side motors. Uses velocity mode. * diff --git a/include/okapi/api/chassis/model/skidSteerModel.hpp b/include/okapi/api/chassis/model/skidSteerModel.hpp index 6a2ae6f0..7994c14e 100644 --- a/include/okapi/api/chassis/model/skidSteerModel.hpp +++ b/include/okapi/api/chassis/model/skidSteerModel.hpp @@ -87,6 +87,18 @@ class SkidSteerModel : public ChassisModel { */ void arcade(double iforwardSpeed, double iyaw, double ithreshold = 0) override; + /** + * Drive the robot with a curvature drive layout. The robot drives in constant radius turns + * where you control the curvature (inverse of radius) you drive in. This is advantageous + * because the forward speed will not affect the rate of turning. The algorithm switches to + * arcade if the forward speed is 0. Uses voltage mode. + * + * @param iforwardSpeed speed in the forward direction + * @param icurvature curvature (inverse of radius) to drive in + * @param ithreshold deadband on joystick values + */ + void curvature(double iforwardSpeed, double icurvature, double ithreshold = 0) override; + /** * Power the left side motors. Uses velocity mode. * diff --git a/include/okapi/api/chassis/model/xDriveModel.hpp b/include/okapi/api/chassis/model/xDriveModel.hpp index 29874eab..07781be8 100644 --- a/include/okapi/api/chassis/model/xDriveModel.hpp +++ b/include/okapi/api/chassis/model/xDriveModel.hpp @@ -8,6 +8,7 @@ #include "okapi/api/chassis/model/chassisModel.hpp" #include "okapi/api/device/motor/abstractMotor.hpp" #include "okapi/api/device/rotarysensor/continuousRotarySensor.hpp" +#include "okapi/api/units/QAngle.hpp" namespace okapi { class XDriveModel : public ChassisModel { @@ -113,6 +114,18 @@ class XDriveModel : public ChassisModel { */ void arcade(double iforwardSpeed, double iyaw, double ithreshold = 0) override; + /** + * Drive the robot with a curvature drive layout. The robot drives in constant radius turns + * where you control the curvature (inverse of radius) you drive in. This is advantageous + * because the forward speed will not affect the rate of turning. The algorithm switches to + * arcade if the forward speed is 0. Uses voltage mode. + * + * @param iforwardSpeed speed forward direction + * @param icurvature curvature (inverse of radius) to drive in + * @param ithreshold deadband on joystick values + */ + void curvature(double iforwardSpeed, double icurvature, double ithreshold = 0) override; + /** * Drive the robot with an arcade drive layout. Uses voltage mode. * @@ -124,6 +137,27 @@ class XDriveModel : public ChassisModel { virtual void xArcade(double irightSpeed, double iforwardSpeed, double iyaw, double ithreshold = 0); + /** + * Drive the robot with a field-oriented arcade drive layout. Uses voltage mode. + * For example: + * Both `fieldOrientedXArcade(1, 0, 0, 0_deg)` and `fieldOrientedXArcade(1, 0, 0, 90_deg)` + * will drive the chassis in the forward/north direction. In other words, no matter + * the robot's heading, the robot will move forward/north when you tell it + * to move forward/north and will move right/east when you tell it to move right/east. + * + * + * @param ixSpeed forward speed -- (`+1`) forward, (`-1`) backward + * @param iySpeed sideways speed -- (`+1`) right, (`-1`) left + * @param iyaw turn speed -- (`+1`) clockwise, (`-1`) counter-clockwise + * @param iangle current chassis angle (`0_deg` = no correction, winds clockwise) + * @param ithreshold deadband on joystick values + */ + virtual void fieldOrientedXArcade(double ixSpeed, + double iySpeed, + double iyaw, + QAngle iangle, + double ithreshold = 0); + /** * Power the left side motors. Uses velocity mode. * diff --git a/include/okapi/api/control/async/asyncLinearMotionProfileController.hpp b/include/okapi/api/control/async/asyncLinearMotionProfileController.hpp index 284e10ea..8efcc74f 100644 --- a/include/okapi/api/control/async/asyncLinearMotionProfileController.hpp +++ b/include/okapi/api/control/async/asyncLinearMotionProfileController.hpp @@ -15,9 +15,7 @@ #include #include -extern "C" { -#include "okapi/pathfinder/include/pathfinder.h" -} +#include "squiggles.hpp" namespace okapi { class AsyncLinearMotionProfileController : public AsyncPositionController { @@ -250,16 +248,8 @@ class AsyncLinearMotionProfileController : public AsyncPositionController; - using SegmentPtr = std::unique_ptr; - - struct TrajectoryPair { - SegmentPtr segment; - int length; - }; - std::shared_ptr logger; - std::map paths{}; + std::map> paths{}; PathfinderLimits limits; std::shared_ptr> output; QLength diameter; @@ -283,7 +273,8 @@ class AsyncLinearMotionProfileController : public AsyncPositionController rate); + virtual void executeSinglePath(const std::vector &path, + std::unique_ptr rate); /** * Converts linear "chassis" speed to rotational motor speed. @@ -293,15 +284,8 @@ class AsyncLinearMotionProfileController : public AsyncPositionController &points, const std::string &ipathId, int length); - - /** - * Reads the length of the path in a thread-safe manner. - * - * @param path The path to read from. - * @return The length of the path. - */ - int getPathLength(const TrajectoryPair &path); + std::string getPathErrorMessage(const std::vector &points, + const std::string &ipathId, + int length); }; } // namespace okapi diff --git a/include/okapi/api/control/async/asyncMotionProfileController.hpp b/include/okapi/api/control/async/asyncMotionProfileController.hpp index 6f42823d..3c8b74a4 100644 --- a/include/okapi/api/control/async/asyncMotionProfileController.hpp +++ b/include/okapi/api/control/async/asyncMotionProfileController.hpp @@ -14,11 +14,10 @@ #include "okapi/api/util/logging.hpp" #include "okapi/api/util/timeUtil.hpp" #include +#include #include -extern "C" { -#include "okapi/pathfinder/include/pathfinder.h" -} +#include "squiggles.hpp" namespace okapi { class AsyncMotionProfileController : public AsyncPositionController { @@ -68,6 +67,10 @@ class AsyncMotionProfileController : public AsyncPositionController..csv`. An SD card + * Saves a generated path to a file. Paths are stored as `.csv`. An SD card * must be inserted into the brain and the directory must exist. `idirectory` can be prefixed with * `/usd/`, but it this is not required. * - * @param idirectory The directory to store the path files in + * @param idirectory The directory to store the path file in * @param ipathId The path ID of the generated path */ void storePath(const std::string &idirectory, const std::string &ipathId); /** - * Loads a path from a directory on the SD card containing path CSV files. `/usd/` is + * Loads a path from a directory on the SD card containing a path CSV file. `/usd/` is * automatically prepended to `idirectory` if it is not specified. * * @param idirectory The directory that the path files are stored in @@ -262,17 +265,8 @@ class AsyncMotionProfileController : public AsyncPositionController; - using SegmentPtr = std::unique_ptr; - - struct TrajectoryPair { - SegmentPtr left; - SegmentPtr right; - int length; - }; - std::shared_ptr logger; - std::map paths{}; + std::map> paths{}; PathfinderLimits limits; std::shared_ptr model; ChassisScales scales; @@ -296,7 +290,8 @@ class AsyncMotionProfileController : public AsyncPositionController rate); + virtual void executeSinglePath(const std::vector &path, + std::unique_ptr rate); /** * Converts linear chassis speed to rotational motor speed. @@ -306,8 +301,9 @@ class AsyncMotionProfileController : public AsyncPositionController &points, const std::string &ipathId, int length); + std::string getPathErrorMessage(const std::vector &points, + const std::string &ipathId, + int length); /** * Joins and escapes a directory and file name @@ -319,15 +315,12 @@ class AsyncMotionProfileController : public AsyncPositionController namespace okapi { @@ -16,9 +17,38 @@ struct OdomState { QAngle theta{0_deg}; /** + * Get a string for the current odometry state (optionally with the specified units). + * + * Examples: + * - `OdomState::str(1_m, 1_deg)`: The default (no arguments specified). + * - `OdomState::str(1_tile, 1_radian)`: distance tiles and angle radians. + * + * Throws std::domain_error if the units passed are undefined. + * + * @param idistanceUnit The units you want your distance to be in. This must be an exact, predefined QLength (such as foot, meter, inch, tile etc.). + * @param iangleUnit The units you want your angle to be in. This must be an exact, predefined QAngle (degree or radian). * @return A string representing the state. */ - std::string str() const; + std::string str(QLength idistanceUnit, QAngle iangleUnit) const; + + /** + * Get a string for the current odometry state (optionally with the specified units). + * + * Examples: + * - `OdomState::str(1_m, "_m", 1_deg, "_deg")`: The default (no arguments specified), prints in meters and degrees. + * - `OdomState::str(1_in, "_in", 1_deg, "_deg")` or `OdomState::str(1_in, "\"", 1_deg, "°")`: to print values in inches and degrees with different suffixes. + * - `OdomState::str(6_tile / 100, "%", 360_deg / 100, "%")` to get the distance values in % of the vex field, and angle values in % of a full rotation. + * + * @param idistanceUnit The units you want your distance to be in. The x or y position will be output in multiples of this length. + * @param distUnitName The suffix you as your distance unit. + * @param iangleUnit The units you want your angle to be in. The angle will be output in multiples of this unit. + * @param angleUnitName The suffix you want as your angle unit. + * @return A string representing the state. + */ + std::string str(QLength idistanceUnit = meter, + std::string distUnitName = "_m", + QAngle iangleUnit = degree, + std::string angleUnitName = "_deg") const; bool operator==(const OdomState &rhs) const; diff --git a/include/okapi/api/units/QLength.hpp b/include/okapi/api/units/QLength.hpp index ffcd083b..c102fcb9 100644 --- a/include/okapi/api/units/QLength.hpp +++ b/include/okapi/api/units/QLength.hpp @@ -23,6 +23,7 @@ constexpr QLength inch = 2.54 * centimeter; constexpr QLength foot = 12 * inch; constexpr QLength yard = 3 * foot; constexpr QLength mile = 5280 * foot; +constexpr QLength tile = 24 * inch; inline namespace literals { constexpr QLength operator"" _mm(long double x) { @@ -49,6 +50,9 @@ constexpr QLength operator"" _ft(long double x) { constexpr QLength operator"" _in(long double x) { return static_cast(x) * inch; } +constexpr QLength operator"" _tile(long double x) { + return static_cast(x) * tile; +} constexpr QLength operator"" _mm(unsigned long long int x) { return static_cast(x) * millimeter; } @@ -73,5 +77,8 @@ constexpr QLength operator"" _ft(unsigned long long int x) { constexpr QLength operator"" _in(unsigned long long int x) { return static_cast(x) * inch; } +constexpr QLength operator"" _tile(unsigned long long int x) { + return static_cast(x) * tile; +} } // namespace literals } // namespace okapi diff --git a/include/okapi/api/units/RQuantityName.hpp b/include/okapi/api/units/RQuantityName.hpp new file mode 100644 index 00000000..28e62984 --- /dev/null +++ b/include/okapi/api/units/RQuantityName.hpp @@ -0,0 +1,46 @@ +#include "okapi/api/units/QAngle.hpp" +#include "okapi/api/units/QLength.hpp" +#include "okapi/api/units/QSpeed.hpp" +#include +#include +#include + +#pragma once + +namespace okapi { + +/** +* Returns a short name for a unit. +* For example: `str(1_ft)` will return "ft", so will `1 * foot` or `0.3048_m`. +* Throws std::domain_error when `q` is a unit not defined in this function. +* +* @param q Your unit. Currently only QLength and QAngle are supported. +* @return The short string suffix for that unit. +*/ +template std::string getShortUnitName(QType q) { + const std::unordered_map> shortNameMap = + {{typeid(meter), + { + {meter.getValue(), "m"}, + {decimeter.getValue(), "dm"}, + {centimeter.getValue(), "cm"}, + {millimeter.getValue(), "mm"}, + {kilometer.getValue(), "km"}, + {inch.getValue(), "in"}, + {foot.getValue(), "ft"}, + {yard.getValue(), "yd"}, + {mile.getValue(), "mi"}, + {tile.getValue(), "tile"}, + }}, + {typeid(degree), {{degree.getValue(), "deg"}, {radian.getValue(), "rad"}}}}; + + try { + return shortNameMap.at(typeid(q)).at(q.getValue()); + } catch (const std::out_of_range &e) { + throw std::domain_error( + "You have requested the shortname of an unknown unit somewhere (likely odometry strings). " + "Shortname for provided unit is unspecified. You can override this function to add more " + "names or manually specify the name instead."); + } +} +} // namespace okapi diff --git a/include/okapi/api/util/mathUtil.hpp b/include/okapi/api/util/mathUtil.hpp index 5f02afb8..424a8623 100644 --- a/include/okapi/api/util/mathUtil.hpp +++ b/include/okapi/api/util/mathUtil.hpp @@ -120,12 +120,11 @@ static constexpr std::int8_t adiUpdateRate = 10; * @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); + 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); } /** diff --git a/include/okapi/impl/chassis/controller/chassisControllerBuilder.hpp b/include/okapi/impl/chassis/controller/chassisControllerBuilder.hpp index 8c8fd693..7d11896f 100644 --- a/include/okapi/impl/chassis/controller/chassisControllerBuilder.hpp +++ b/include/okapi/impl/chassis/controller/chassisControllerBuilder.hpp @@ -474,7 +474,7 @@ class ChassisControllerBuilder { TimeUtilFactory closedLoopControllerTimeUtilFactory = TimeUtilFactory(); TimeUtilFactory odometryTimeUtilFactory = TimeUtilFactory(); - AbstractMotor::GearsetRatioPair gearset{AbstractMotor::gearset::invalid,1.0}; + AbstractMotor::GearsetRatioPair gearset{AbstractMotor::gearset::invalid, 1.0}; ChassisScales driveScales{{1, 1}, imev5GreenTPR}; bool differentOdomScales{false}; ChassisScales odomScales{{1, 1}, imev5GreenTPR}; diff --git a/include/okapi/impl/device/motor/motorGroup.hpp b/include/okapi/impl/device/motor/motorGroup.hpp index 35469622..6187c4c6 100644 --- a/include/okapi/impl/device/motor/motorGroup.hpp +++ b/include/okapi/impl/device/motor/motorGroup.hpp @@ -372,6 +372,13 @@ class MotorGroup : public AbstractMotor { */ void controllerSet(double ivalue) override; + /** + * Gets the number of motors in the motor group. + * + * @return size_t + */ + size_t getSize(); + /** * Get the encoder associated with the first motor in this group. * diff --git a/include/okapi/impl/device/rotarysensor/IMU.hpp b/include/okapi/impl/device/rotarysensor/IMU.hpp index 462190e2..98b97dcd 100644 --- a/include/okapi/impl/device/rotarysensor/IMU.hpp +++ b/include/okapi/impl/device/rotarysensor/IMU.hpp @@ -62,6 +62,16 @@ class IMU : public ContinuousRotarySensor { */ std::int32_t reset() override; + /** + * Resets rotation value to desired value + * For example, ``reset(0)`` will reset the sensor to zero. + * But ``reset(90)`` will reset the sensor to 90 degrees. + * + * @param inewAngle desired reset value + * @return ``1`` or ``PROS_ERR``. + */ + std::int32_t reset(double inewAngle); + /** * Calibrate the IMU. Resets the rotation value to zero. Calibration is expected to take two * seconds, but is bounded to five seconds. diff --git a/include/okapi/pathfinder/include/pathfinder.h b/include/okapi/pathfinder/include/pathfinder.h deleted file mode 100644 index 8db9223f..00000000 --- a/include/okapi/pathfinder/include/pathfinder.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef PATHFINDER_H_DEF -#define PATHFINDER_H_DEF - -#include "okapi/pathfinder/include/pathfinder/mathutil.h" -#include "okapi/pathfinder/include/pathfinder/structs.h" - -#include "okapi/pathfinder/include/pathfinder/fit.h" -#include "okapi/pathfinder/include/pathfinder/spline.h" -#include "okapi/pathfinder/include/pathfinder/trajectory.h" - -#include "okapi/pathfinder/include/pathfinder/modifiers/tank.h" -#include "okapi/pathfinder/include/pathfinder/modifiers/swerve.h" - -#include "okapi/pathfinder/include/pathfinder/followers/encoder.h" -#include "okapi/pathfinder/include/pathfinder/followers/distance.h" - -#include "okapi/pathfinder/include/pathfinder/io.h" - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/fit.h b/include/okapi/pathfinder/include/pathfinder/fit.h deleted file mode 100644 index 39eea48f..00000000 --- a/include/okapi/pathfinder/include/pathfinder/fit.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef PATHFINDER_FIT_H_DEF -#define PATHFINDER_FIT_H_DEF - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "okapi/pathfinder/include/pathfinder/lib.h" -#include "okapi/pathfinder/include/pathfinder/structs.h" - -CAPI void pf_fit_hermite_pre(Waypoint a, Waypoint b, Spline *s); -CAPI void pf_fit_hermite_cubic(Waypoint a, Waypoint b, Spline *s); -CAPI void pf_fit_hermite_quintic(Waypoint a, Waypoint b, Spline *s); - -#define FIT_HERMITE_CUBIC &pf_fit_hermite_cubic -#define FIT_HERMITE_QUINTIC &pf_fit_hermite_quintic - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/followers/distance.h b/include/okapi/pathfinder/include/pathfinder/followers/distance.h deleted file mode 100644 index 21c6e6e6..00000000 --- a/include/okapi/pathfinder/include/pathfinder/followers/distance.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef PATHFINDER_FOL_DISTANCE_H_DEF -#define PATHFINDER_FOL_DISTANCE_H_DEF - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "okapi/pathfinder/include/pathfinder/lib.h" -#include "okapi/pathfinder/include/pathfinder/structs.h" - -CAPI typedef struct { - double kp, ki, kd, kv, ka; -} FollowerConfig; - -CAPI typedef struct { - double last_error, heading, output; - int segment, finished; -} DistanceFollower; - -CAPI double pathfinder_follow_distance(FollowerConfig c, DistanceFollower *follower, Segment *trajectory, int trajectory_length, double distance); - -CAPI double pathfinder_follow_distance2(FollowerConfig c, DistanceFollower *follower, Segment segment, int trajectory_length, double distance); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/followers/encoder.h b/include/okapi/pathfinder/include/pathfinder/followers/encoder.h deleted file mode 100644 index c1d9cfd9..00000000 --- a/include/okapi/pathfinder/include/pathfinder/followers/encoder.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef PATHFINDER_FOL_ENCODER_H_DEF -#define PATHFINDER_FOL_ENCODER_H_DEF - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "okapi/pathfinder/include/pathfinder/structs.h" - -typedef struct { - int initial_position, ticks_per_revolution; - double wheel_circumference; - double kp, ki, kd, kv, ka; -} EncoderConfig; - -typedef struct { - double last_error, heading, output; - int segment, finished; -} EncoderFollower; - - -double pathfinder_follow_encoder(EncoderConfig c, EncoderFollower *follower, Segment *trajectory, int trajectory_length, int encoder_tick); - -double pathfinder_follow_encoder2(EncoderConfig c, EncoderFollower *follower, Segment segment, int trajectory_length, int encoder_tick); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/io.h b/include/okapi/pathfinder/include/pathfinder/io.h deleted file mode 100644 index 210bb269..00000000 --- a/include/okapi/pathfinder/include/pathfinder/io.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef PATHFINDER_IO_H_DEF -#define PATHFINDER_IO_H_DEF - -#include -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "okapi/pathfinder/include/pathfinder/structs.h" -#include "okapi/pathfinder/include/pathfinder/lib.h" - -#define CSV_LEADING_STRING "dt,x,y,position,velocity,acceleration,jerk,heading\n" - -CAPI void intToBytes(int n, char *bytes); -CAPI int bytesToInt(char *bytes); -CAPI void longToBytes(unsigned long long n, char *bytes); -CAPI unsigned long long bytesToLong(char *bytes); -CAPI double longToDouble(unsigned long long l); -CAPI unsigned long long doubleToLong(double d); -CAPI void doubleToBytes(double n, char *bytes); -CAPI double bytesToDouble(char *bytes); - -CAPI void pathfinder_serialize(FILE *fp, Segment *trajectory, int trajectory_length); -CAPI int pathfinder_deserialize(FILE *fp, Segment *target); - -CAPI void pathfinder_serialize_csv(FILE *fp, Segment *trajectory, int trajectory_length); -CAPI int pathfinder_deserialize_csv(FILE *fp, Segment *target); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/lib.h b/include/okapi/pathfinder/include/pathfinder/lib.h deleted file mode 100644 index 0ba47afe..00000000 --- a/include/okapi/pathfinder/include/pathfinder/lib.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef PATHFINDER_LIB_H_DEF -#define PATHFINDER_LIB_H_DEF - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) - #define CAPI __declspec(dllexport) -#else - #define CAPI -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/mathutil.h b/include/okapi/pathfinder/include/pathfinder/mathutil.h deleted file mode 100644 index db3ebcbc..00000000 --- a/include/okapi/pathfinder/include/pathfinder/mathutil.h +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#ifndef PATHFINDER_MATH_UTIL_H_DEF -#define PATHFINDER_MATH_UTIL_H_DEF - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "okapi/pathfinder/include/pathfinder/lib.h" - -#define PI 3.14159265358979323846 -#define TAU PI*2 - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -CAPI double bound_radians(double angle); - -CAPI double r2d(double angleInRads); - -CAPI double d2r(double angleInDegrees); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/modifiers/swerve.h b/include/okapi/pathfinder/include/pathfinder/modifiers/swerve.h deleted file mode 100644 index 60be7500..00000000 --- a/include/okapi/pathfinder/include/pathfinder/modifiers/swerve.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef PATHFINDER_MOD_SWERVE_H_DEF -#define PATHFINDER_MOD_SWERVE_H_DEF - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "okapi/pathfinder/include/pathfinder/lib.h" -#include "okapi/pathfinder/include/pathfinder/structs.h" - -CAPI typedef enum { - SWERVE_DEFAULT -} SWERVE_MODE; - -CAPI void pathfinder_modify_swerve(Segment *original, int length, Segment *front_left, Segment *front_right, - Segment *back_left, Segment *back_right, double wheelbase_width, double wheelbase_depth, SWERVE_MODE mode); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/modifiers/tank.h b/include/okapi/pathfinder/include/pathfinder/modifiers/tank.h deleted file mode 100644 index f72db638..00000000 --- a/include/okapi/pathfinder/include/pathfinder/modifiers/tank.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PATHFINDER_MOD_TANK_H_DEF -#define PATHFINDER_MOD_TANK_H_DEF - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "okapi/pathfinder/include/pathfinder/lib.h" -#include "okapi/pathfinder/include/pathfinder/structs.h" - -CAPI void pathfinder_modify_tank(Segment *original, int length, Segment *left, Segment *right, double wheelbase_width); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/spline.h b/include/okapi/pathfinder/include/pathfinder/spline.h deleted file mode 100644 index 8c68ae12..00000000 --- a/include/okapi/pathfinder/include/pathfinder/spline.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef PATHFINDER_SPLINE_H_DEF -#define PATHFINDER_SPLINE_H_DEF - -#include "okapi/pathfinder/include/pathfinder/lib.h" -#include "okapi/pathfinder/include/pathfinder/structs.h" - -#define PATHFINDER_SAMPLES_FAST (int)1000 -#define PATHFINDER_SAMPLES_LOW (int)PATHFINDER_SAMPLES_FAST*10 -#define PATHFINDER_SAMPLES_HIGH (int)PATHFINDER_SAMPLES_LOW*10 - -CAPI Coord pf_spline_coords(Spline s, double percentage); -CAPI double pf_spline_deriv(Spline s, double percentage); -CAPI double pf_spline_deriv_2(double a, double b, double c, double d, double e, double k, double p); -CAPI double pf_spline_angle(Spline s, double percentage); - -CAPI double pf_spline_distance(Spline *s, int sample_count); -CAPI double pf_spline_progress_for_distance(Spline s, double distance, int sample_count); - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/structs.h b/include/okapi/pathfinder/include/pathfinder/structs.h deleted file mode 100644 index 5c424d39..00000000 --- a/include/okapi/pathfinder/include/pathfinder/structs.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef PATHFINDER_STRUCT_H_DEF -#define PATHFINDER_STRUCT_H_DEF - -#include "okapi/pathfinder/include/pathfinder/lib.h" - -CAPI typedef struct { - double x, y, angle; -} Waypoint; - -CAPI typedef struct { - double a, b, c, d, e; - double x_offset, y_offset, angle_offset, knot_distance, arc_length; -} Spline; - -CAPI typedef struct { - double x, y; -} Coord; - -CAPI typedef struct { - double dt, x, y, position, velocity, acceleration, jerk, heading; -} Segment; - -CAPI typedef struct { - double dt, max_v, max_a, max_j, src_v, src_theta, dest_pos, dest_v, dest_theta; - int sample_count; -} TrajectoryConfig; - -CAPI typedef struct { - int filter1, filter2, length; - double dt, u, v, impulse; -} TrajectoryInfo; - -CAPI typedef struct { - Spline *saptr; - double *laptr; - double totalLength; - int length; - int path_length; - TrajectoryInfo info; - TrajectoryConfig config; -} TrajectoryCandidate; - -#endif \ No newline at end of file diff --git a/include/okapi/pathfinder/include/pathfinder/trajectory.h b/include/okapi/pathfinder/include/pathfinder/trajectory.h deleted file mode 100644 index fb9a410f..00000000 --- a/include/okapi/pathfinder/include/pathfinder/trajectory.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef PATHFINDER_TRAJECTORY_H_DEF -#define PATHFINDER_TRAJECTORY_H_DEF - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "okapi/pathfinder/include/pathfinder/lib.h" -#include "okapi/pathfinder/include/pathfinder/structs.h" - -CAPI int pathfinder_prepare(Waypoint *path, int path_length, void (*fit)(Waypoint,Waypoint,Spline*), int sample_count, double dt, - double max_velocity, double max_acceleration, double max_jerk, TrajectoryCandidate *cand); -CAPI int pathfinder_generate(TrajectoryCandidate *c, Segment *segments); - -CAPI void pf_trajectory_copy(Segment *src, Segment *dest, int length); - -CAPI TrajectoryInfo pf_trajectory_prepare(TrajectoryConfig c); -CAPI int pf_trajectory_create(TrajectoryInfo info, TrajectoryConfig c, Segment *seg); -CAPI int pf_trajectory_fromSecondOrderFilter(int filter_1_l, int filter_2_l, - double dt, double u, double v, double impulse, int len, Segment *t); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/okapi/squiggles/constraints.hpp b/include/okapi/squiggles/constraints.hpp new file mode 100644 index 00000000..f59089be --- /dev/null +++ b/include/okapi/squiggles/constraints.hpp @@ -0,0 +1,65 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _SQUIGGLES_CONSTRAINTS_HPP_ +#define _SQUIGGLES_CONSTRAINTS_HPP_ + +#include +#include + +namespace squiggles { +struct Constraints { + /** + * Defines the motion constraints for a path. + * + * @param imax_vel The maximum allowable velocity for the robot in meters per + * second. + * @param imax_accel The maximum allowable acceleration for the robot in + * meters per second per second. + * @param imax_jerk The maximum allowable jerk for the robot in meters per + * second per second per second (m/s^3). + * @param imax_curvature The maximum allowable change in heading in radians + * per second. This is not set to the numeric limits by + * default as that will allow for wild paths. + * @param imin_accel The minimum allowable acceleration for the robot in + * meters per second per second. + */ + Constraints(double imax_vel, + double imax_accel = std::numeric_limits::max(), + double imax_jerk = std::numeric_limits::max(), + double imax_curvature = 1000, + double imin_accel = std::nan("")) + : max_vel(imax_vel), + max_accel(imax_accel), + max_jerk(imax_jerk), + max_curvature(imax_curvature) { + if (imax_accel == std::numeric_limits::max()) { + min_accel = std::numeric_limits::lowest(); + } else { + min_accel = std::isnan(imin_accel) ? -imax_accel : imin_accel; + } + } + + /** + * Serializes the Constraints data for debugging. + * + * @return The Constraints data. + */ + std::string to_string() const { + return "Constraints: {max_vel: " + std::to_string(max_vel) + + ", max_accel: " + std::to_string(max_accel) + + ", max_jerk: " + std::to_string(max_jerk) + + ", min_accel: " + std::to_string(min_accel) + "}"; + } + + double max_vel; + double max_accel; + double max_jerk; + double min_accel; + double max_curvature; +}; +} // namespace squiggles +#endif diff --git a/include/okapi/squiggles/geometry/controlvector.hpp b/include/okapi/squiggles/geometry/controlvector.hpp new file mode 100644 index 00000000..c279bd49 --- /dev/null +++ b/include/okapi/squiggles/geometry/controlvector.hpp @@ -0,0 +1,62 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _GEOMETRY_CONTROL_VECTOR_HPP_ +#define _GEOMETRY_CONTROL_VECTOR_HPP_ + +#include +#include + +#include "pose.hpp" + +namespace squiggles { +class ControlVector { + public: + /** + * A vector used to specify a state along a hermite spline. + * + * @param ipose The 2D position and heading. + * @param ivel The velocity component of the vector. + * @param iaccel The acceleration component of the vector. + * @param ijerk The jerk component of the vector. + */ + ControlVector(Pose ipose, + double ivel = std::nan(""), + double iaccel = 0.0, + double ijerk = 0.0) + : pose(ipose), vel(ivel), accel(iaccel), jerk(ijerk) {} + + ControlVector() = default; + + /** + * Serializes the Control Vector data for debugging. + * + * @return The Control Vector data. + */ + std::string to_string() const { + return "ControlVector: {" + pose.to_string() + + ", v: " + std::to_string(vel) + ", a: " + std::to_string(accel) + + ", j: " + std::to_string(jerk) + "}"; + } + + std::string to_csv() const { + return pose.to_csv() + "," + std::to_string(vel) + "," + + std::to_string(accel) + "," + std::to_string(jerk); + } + + bool operator==(const ControlVector& other) const { + return pose == other.pose && nearly_equal(vel, other.vel) && + nearly_equal(accel, other.accel) && nearly_equal(jerk, other.jerk); + } + + Pose pose; + double vel; + double accel; + double jerk; +}; +} // namespace squiggles + +#endif \ No newline at end of file diff --git a/include/okapi/squiggles/geometry/pose.hpp b/include/okapi/squiggles/geometry/pose.hpp new file mode 100644 index 00000000..b3b76907 --- /dev/null +++ b/include/okapi/squiggles/geometry/pose.hpp @@ -0,0 +1,67 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _GEOMETRY_POSE_HPP_ +#define _GEOMETRY_POSE_HPP_ + +#include +#include + +#include "math/utils.hpp" + +namespace squiggles { +class Pose { + public: + /** + * Specifies a point and heading in 2D space. + * + * @param ix The x position of the point in meters. + * @param iy The y position of the point in meters. + * @param iyaw The heading at the point in radians. + */ + Pose(double ix, double iy, double iyaw) : x(ix), y(iy), yaw(iyaw) {} + + Pose() = default; + + /** + * Calculates the Euclidean distance between this pose and another. + * + * @param other The point from which the distance will be calculated. + * + * @return The distance between this pose and Other. + */ + double dist(const Pose& other) const { + return std::sqrt((x - other.x) * (x - other.x) + + (y - other.y) * (y - other.y)); + } + + /** + * Serializes the Pose data for debugging. + * + * @return The Pose data. + */ + std::string to_string() const { + return "Pose: {x: " + std::to_string(x) + ", y: " + std::to_string(y) + + ", yaw: " + std::to_string(yaw) + "}"; + } + + std::string to_csv() const { + return std::to_string(x) + "," + std::to_string(y) + "," + + std::to_string(yaw); + } + + bool operator==(const Pose& other) const { + return nearly_equal(x, other.x) && nearly_equal(y, other.y) && + nearly_equal(yaw, other.yaw); + } + + double x; + double y; + double yaw; +}; +} // namespace squiggles + +#endif \ No newline at end of file diff --git a/include/okapi/squiggles/geometry/profilepoint.hpp b/include/okapi/squiggles/geometry/profilepoint.hpp new file mode 100644 index 00000000..e6eed094 --- /dev/null +++ b/include/okapi/squiggles/geometry/profilepoint.hpp @@ -0,0 +1,100 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _GEOMETRY_PROFILE_POINT_HPP_ +#define _GEOMETRY_PROFILE_POINT_HPP_ + +#include +#include +#include + +#include "controlvector.hpp" +#include "math/utils.hpp" + +namespace squiggles { +struct ProfilePoint { + /** + * Defines a state along a motion profiled path. + * + * @param ivector The pose and associated dynamics at this state in the path. + * @param iwheel_velocities The component of the robot's velocity provided by + * each wheel in meters per second. + * @param icurvature The degree to which the curve deviates from a straight + * line at this point in 1 / meters. + * @param itime The timestamp for this state relative to the start of the + * path in seconds. + */ + ProfilePoint(ControlVector ivector, + std::vector iwheel_velocities, + double icurvature, + double itime) + : vector(ivector), + wheel_velocities(iwheel_velocities), + curvature(icurvature), + time(itime) {} + + ProfilePoint() = default; + + /** + * Serializes the Profile Point data for debugging. + * + * @return The Profile Point data. + */ + std::string to_string() const { + std::string wheels = "{"; + for (auto& w : wheel_velocities) { + wheels += std::to_string(w); + wheels += ", "; + } + wheels += "}"; + return "ProfilePoint: {" + vector.to_string() + ", wheels: " + wheels + + ", k: " + std::to_string(curvature) + + ", t: " + std::to_string(time) + "}"; + } + + std::string to_csv() const { + std::string wheels = ""; + for (auto& w : wheel_velocities) { + wheels += ","; + wheels += std::to_string(w); + } + return vector.to_csv() + "," + std::to_string(curvature) + "," + + std::to_string(time) + wheels; + } + + bool operator==(const ProfilePoint& other) const { + for (std::size_t i = 0; i < wheel_velocities.size(); ++i) { + if (!nearly_equal(wheel_velocities[i], other.wheel_velocities[i])) { + return false; + } + } + return vector == other.vector && nearly_equal(curvature, other.curvature) && + nearly_equal(time, other.time); + } + + friend std::ostream& operator<<(std::ostream& os, const ProfilePoint& p) { + return os << "ProfilePoint(ControlVector(Pose(" + + std::to_string(p.vector.pose.x) + "," + + std::to_string(p.vector.pose.y) + "," + + std::to_string(p.vector.pose.yaw) + ")," + + std::to_string(p.vector.vel) + "," + + std::to_string(p.vector.accel) + "," + + std::to_string(p.vector.jerk) + "),{" + + std::to_string(p.wheel_velocities[0]) + "," + + std::to_string(p.wheel_velocities[1]) + "}," + + std::to_string(p.curvature) + "," + std::to_string(p.time) + + "),"; + // return os << p.to_string(); + } + + ControlVector vector; + std::vector wheel_velocities; + double curvature; + double time; +}; +} // namespace squiggles + +#endif \ No newline at end of file diff --git a/include/okapi/squiggles/io.hpp b/include/okapi/squiggles/io.hpp new file mode 100644 index 00000000..c22ed970 --- /dev/null +++ b/include/okapi/squiggles/io.hpp @@ -0,0 +1,56 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _SQUIGGLES_IO_HPP_ +#define _SQUIGGLES_IO_HPP_ + +#include +#include + +#include "geometry/profilepoint.hpp" + +namespace squiggles { +/** + * Writes the path data to a CSV file. + * + * @param out The output stream to write the CSV data to. This is usually a + * file. + * @param path The path to serialized + * + * @return 0 if the path was serialized succesfully or -1 if an error occurred. + */ +int serialize_path(std::ostream& out, std::vector path); + +/** + * Converts CSV data into a path. + * + * @param in The input stream containing the CSV data. This is usually a file. + * + * @return The path specified by the CSV data or std::nullopt if de-serializing + * the path was unsuccessful. + */ +std::optional> deserialize_path(std::istream& in); + +/** + * Converts CSV data from the Pathfinder library's format to a Squiggles path. + * + * NOTE: this code translates data from Jaci Brunning's Pathfinder library. + * The source for that library can be found at: + * https://github.com/JaciBrunning/Pathfinder/ + * + * @param left The input stream containing the left wheels' CSV data. This is + * usually a file. + * @param right The input stream containing the right wheels' CSV data. This is + * usually a file. + * + * @return The path specified by the CSV data or std::nullopt if de-serializing + * the path was unsuccessful. + */ +std::optional> +deserialize_pathfinder_path(std::istream& left, std::istream& right); +} // namespace squiggles + +#endif diff --git a/include/okapi/squiggles/math/quinticpolynomial.hpp b/include/okapi/squiggles/math/quinticpolynomial.hpp new file mode 100644 index 00000000..f12580fc --- /dev/null +++ b/include/okapi/squiggles/math/quinticpolynomial.hpp @@ -0,0 +1,65 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _MATH_QUINTIC_POLYNOMIAL_HPP_ +#define _MATH_QUINTIC_POLYNOMIAL_HPP_ + +#include + +namespace squiggles { +class QuinticPolynomial { + public: + /** + * Defines the polynomial function for a spline in one dimension. + * + * @param s_p The starting position of the curve in meters. + * @param s_v The starting velocity of the curve in meters per second. + * @param s_a The starting acceleration of the curve in meters per second per + * second. + * @param g_p The goal or ending position of the curve in meters. + * @param g_v The goal or ending velocity of the curve in meters per second. + * @param g_a The goal or ending acceleration of the curve in meters per + * second per second. + * @param t The desired duration for the curve in seconds. + */ + QuinticPolynomial(double s_p, + double s_v, + double s_a, + double g_p, + double g_v, + double g_a, + double t); + + /** + * Calculates the values of the polynomial and its derivatives at the given + * time stamp. + */ + double calc_point(double t); + double calc_first_derivative(double t); + double calc_second_derivative(double t); + double calc_third_derivative(double t); + + /** + * Serializes the Quintic Polynomial data for debugging. + * + * @return The Quintic Polynomial data. + */ + std::string to_string() const { + return "QuinticPolynomial: {0: " + std::to_string(a0) + + " 1: " + std::to_string(a1) + " 2: " + std::to_string(a2) + + " 3: " + std::to_string(a3) + " 4: " + std::to_string(a4) + + " 5: " + std::to_string(a5) + "}"; + } + + protected: + /** + * The coefficients for each term of the polynomial. + */ + double a0, a1, a2, a3, a4, a5; +}; +} // namespace squiggles + +#endif \ No newline at end of file diff --git a/include/okapi/squiggles/math/utils.hpp b/include/okapi/squiggles/math/utils.hpp new file mode 100644 index 00000000..cca3da0c --- /dev/null +++ b/include/okapi/squiggles/math/utils.hpp @@ -0,0 +1,61 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _MATH_UTILS_HPP_ +#define _MATH_UTILS_HPP_ + +#include +#include + +namespace squiggles { +/** + * Returns the sign value of the given value. + * + * @return 1 if the value is positive, -1 if the value is negative, and 0 if + * the value is 0. + */ +template inline int sgn(T v) { + return (v > T(0)) - (v < T(0)); +} + +inline bool +nearly_equal(const double& a, const double& b, double epsilon = 1e-5) { + return std::fabs(a - b) < epsilon; +} +} // namespace squiggles + +namespace std { +// Copied from https://github.com/emsr/cxx_linear +template +constexpr std::enable_if_t< + std::is_floating_point_v<_Float> && + __cplusplus <= 201703L, // Only defines this function if C++ standard < 20 + _Float> +lerp(_Float __a, _Float __b, _Float __t) { + if (std::isnan(__a) || std::isnan(__b) || std::isnan(__t)) + return std::numeric_limits<_Float>::quiet_NaN(); + else if ((__a <= _Float{0} && __b >= _Float{0}) || + (__a >= _Float{0} && __b <= _Float{0})) + // ab <= 0 but product could overflow. +#ifndef FMA + return __t * __b + (_Float{1} - __t) * __a; +#else + return std::fma(__t, __b, (_Float{1} - __t) * __a); +#endif + else if (__t == _Float{1}) + return __b; + else { // monotonic near t == 1. +#ifndef FMA + const auto __x = __a + __t * (__b - __a); +#else + const auto __x = std::fma(__t, __b - __a, __a); +#endif + return (__t > _Float{1}) == (__b > __a) ? std::max(__b, __x) + : std::min(__b, __x); + } +} +} // namespace std +#endif \ No newline at end of file diff --git a/include/okapi/squiggles/physicalmodel/passthroughmodel.hpp b/include/okapi/squiggles/physicalmodel/passthroughmodel.hpp new file mode 100644 index 00000000..1db2a17a --- /dev/null +++ b/include/okapi/squiggles/physicalmodel/passthroughmodel.hpp @@ -0,0 +1,38 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _PHYSICAL_MODEL_PASSTHROUGH_MODEL_HPP_ +#define _PHYSICAL_MODEL_PASSTHROUGH_MODEL_HPP_ + +#include "physicalmodel/physicalmodel.hpp" + +namespace squiggles { +class PassthroughModel : public PhysicalModel { + public: + /** + * Defines a Physical Model that imposes no constraints of its own. + */ + PassthroughModel() = default; + + Constraints constraints([[maybe_unused]] const Pose pose, + [[maybe_unused]] double curvature, + double vel) override { + return Constraints(vel); + }; + + std::vector + linear_to_wheel_vels([[maybe_unused]] double lin_vel, + [[maybe_unused]] double curvature) override { + return std::vector{}; + } + + std::string to_string() const override { + return "PassthroughModel {}"; + } +}; +} // namespace squiggles + +#endif diff --git a/include/okapi/squiggles/physicalmodel/physicalmodel.hpp b/include/okapi/squiggles/physicalmodel/physicalmodel.hpp new file mode 100644 index 00000000..5c22a4ca --- /dev/null +++ b/include/okapi/squiggles/physicalmodel/physicalmodel.hpp @@ -0,0 +1,43 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _PHYSICAL_MODEL_PHYSICAL_MODEL_HPP_ +#define _PHYSICAL_MODEL_PHYSICAL_MODEL_HPP_ + +#include "constraints.hpp" +#include "geometry/pose.hpp" + +namespace squiggles { +class PhysicalModel { + public: + /** + * Calculate a set of stricter constraints for the path at the given state + * than the general constraints based on the robot's kinematics. + * + * @param pose The 2D pose for this state in the path. + * @param curvature The change in heading at this state in the path in 1 / + * meters. + * @param vel The linear velocity at this state in the path in meters per + * second. + */ + virtual Constraints + constraints(const Pose pose, double curvature, double vel) = 0; + + /** + * Converts a linear velocity and desired curvature into the component for + * each wheel of the robot. + * + * @param linear The linear velocity for the robot in meters per second. + * @param curvature The change in heading for the robot in 1 / meters. + */ + virtual std::vector linear_to_wheel_vels(double linear, + double curvature) = 0; + + virtual std::string to_string() const = 0; +}; +} // namespace squiggles + +#endif diff --git a/include/okapi/squiggles/physicalmodel/tankmodel.hpp b/include/okapi/squiggles/physicalmodel/tankmodel.hpp new file mode 100644 index 00000000..9f0709b2 --- /dev/null +++ b/include/okapi/squiggles/physicalmodel/tankmodel.hpp @@ -0,0 +1,45 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _PHYSICAL_MODEL_TANK_MODEL_HPP_ +#define _PHYSICAL_MODEL_TANK_MODEL_HPP_ + +#include +#include + +#include "physicalmodel/physicalmodel.hpp" + +namespace squiggles { +class TankModel : public PhysicalModel { + public: + /** + * Defines a model of a tank drive or differential drive robot. + * + * @param itrack_width The distance between the the wheels on each side of the + * robot in meters. + * @param ilinear_constraints The maximum values for the robot's movement. + */ + TankModel(double itrack_width, Constraints ilinear_constraints); + + Constraints + constraints(const Pose pose, double curvature, double vel) override; + + std::vector linear_to_wheel_vels(double lin_vel, + double curvature) override; + + std::string to_string() const override; + + private: + double vel_constraint(const Pose pose, double curvature, double vel); + std::tuple + accel_constraint(const Pose pose, double curvature, double vel) const; + + double track_width; + Constraints linear_constraints; +}; +} // namespace squiggles + +#endif \ No newline at end of file diff --git a/include/okapi/squiggles/spline.hpp b/include/okapi/squiggles/spline.hpp new file mode 100644 index 00000000..4ee5991f --- /dev/null +++ b/include/okapi/squiggles/spline.hpp @@ -0,0 +1,310 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _SQUIGGLES_SPLINE_HPP_ +#define _SQUIGGLES_SPLINE_HPP_ + +#include +#include +#include + +#include "constraints.hpp" +#include "geometry/controlvector.hpp" +#include "geometry/profilepoint.hpp" +#include "math/quinticpolynomial.hpp" +#include "physicalmodel/passthroughmodel.hpp" +#include "physicalmodel/physicalmodel.hpp" + +namespace squiggles { +class SplineGenerator { + public: + /** + * Generates curves that match the given motion constraints. + * + * @param iconstraints The maximum allowable values for the robot's motion. + * @param imodel The robot's physical characteristics and constraints + * @param idt The difference in time in seconds between each state for the + * generated paths. + */ + SplineGenerator(Constraints iconstraints, + std::shared_ptr imodel = + std::make_shared(), + double idt = 0.1); + + /** + * Creates a motion profiled path between the given waypoints. + * + * @param iwaypoints The list of poses that the robot should reach along the + * path. + * @param fast If true, the path optimization process will stop as soon as the + * constraints are met. If false, the optimizer will find the + * smoothest possible path between the points. + * + * @return A series of robot states defining a path between the poses. + */ + std::vector generate(std::vector iwaypoints, + bool fast = false); + std::vector generate(std::initializer_list iwaypoints, + bool fast = false); + + /** + * Creates a motion profiled path between the given waypoints. + * + * @param iwaypoints The list of vectors that the robot should reach along the + * path. + * + * @return A series of robot states defining a path between the vectors. + */ + std::vector generate(std::vector iwaypoints); + std::vector + generate(std::initializer_list iwaypoints); + + protected: + /** + * The maximum allowable values for the robot's motion. + */ + Constraints constraints; + + /** + * Defines the physical structure of the robot and translates the linear + * kinematics to wheel velocities. + */ + std::shared_ptr model; + + /** + * The time difference between each value in the generated path. + */ + double dt; + + /** + * The minimum and maximum durations for a path to take. A larger range allows + * for longer possible paths at the expense of a longer path generation time. + */ + const int T_MIN = 2; + const int T_MAX = 15; + const int MAX_GRAD_DESCENT_ITERATIONS = 10; + + /** + * This is factor is used to create a "dummy velocity" in the initial path + * generation step one or both of the preferred start or end velocities is + * zero. The velocity will be replaced with the preferred start/end velocity + * in parameterization but a nonzero velocity is needed for the spline + * calculation. + * + * This was 1.2 in the WPILib example but that large of a value seems to + * create wild paths, 0.12 worked better in testing with VEX-sized paths. + */ + public: + const double K_DEFAULT_VEL = 1.0; + + /** + * The output of the initial, "naive" generation step. We discard the + * derivative values to replace them with values from a motion profile. + */ + + struct GeneratedPoint { + GeneratedPoint(Pose ipose, double icurvature = 0.0) + : pose(ipose), curvature(icurvature) {} + + std::string to_string() const { + return "GeneratedPoint: {" + pose.to_string() + + ", curvature: " + std::to_string(curvature) + "}"; + } + + Pose pose; + double curvature; + }; + + /** + * An intermediate value used in the "naive" generation step. Contains the + * final GeneratedPoint value that will be returned as well as the spline's + * derivative values to perform the initial check against the constraints. + */ + struct GeneratedVector { + GeneratedVector(GeneratedPoint ipoint, + double ivel, + double iaccel, + double ijerk) + : point(ipoint), vel(ivel), accel(iaccel), jerk(ijerk) {} + + GeneratedPoint point; + double vel; + double accel; + double jerk; + + std::string to_string() const { + return "GeneratedVector: {" + point.to_string() + + ", vel: " + std::to_string(vel) + + ", accel: " + std::to_string(accel) + + ", jerk: " + std::to_string(jerk) + "}"; + } + }; + + std::vector gen_single_raw_path(ControlVector start, + ControlVector end, + int duration, + double start_vel, + double end_vel); + /** + * Runs a Gradient Descent algorithm to minimize the linear acceleration, + * linear jerk, and curvature for the generated path. + * + * This is used when there is not a start/end velocity specified for a given + * path. + */ + std::vector + gradient_descent(ControlVector& start, ControlVector& end, bool fast); + + /** + * An intermediate value used in the parameterization step. Adds the + * constrained values from the motion profile to the output from the "naive" + * generation step. + */ + struct ConstrainedState { + ConstrainedState(Pose ipose, + double icurvature, + double idistance, + double imax_vel, + double imin_accel, + double imax_accel) + : pose(ipose), + curvature(icurvature), + distance(idistance), + max_vel(imax_vel), + min_accel(imin_accel), + max_accel(imax_accel) {} + + ConstrainedState() = default; + + Pose pose = Pose(); + double curvature = 0; + double distance = 0; + double max_vel = 0; + double min_accel = 0; + double max_accel = 0; + + std::string to_string() const { + return "ConstrainedState: {x: " + std::to_string(pose.x) + + ", y: " + std::to_string(pose.y) + + ", yaw: " + std::to_string(pose.yaw) + + ", k: " + std::to_string(curvature) + + ", dist: " + std::to_string(distance) + + ", v: " + std::to_string(max_vel) + + ", min_a: " + std::to_string(min_accel) + + ", max_a: " + std::to_string(max_accel) + "}"; + } + }; + + /** + * The actual function called by the "generate" functions. + * + * @param start An iterator pointing to the first ControlVector in the path + * @param end An iterator pointting to the last ControlVector in the path + * + * @return The points from each path concatenated together + */ + template + std::vector _generate(Iter start, Iter end, bool fast); + + public: + /** + * Performs the "naive" generation step. + * + * This step calculates the spline polynomials that fit within the + * SplineGenerator's acceleration and jerk constraints and returns the points + * that form the curve. + */ + std::vector + gen_raw_path(ControlVector& start, ControlVector& end, bool fast); + + /** + * Imposes a linear motion profile on the raw path. + * + * This step creates the velocity and acceleration values to command the robot + * at each point along the curve. + */ + std::vector + parameterize(const ControlVector start, + const ControlVector end, + const std::vector& raw_path, + const double preferred_start_vel, + const double preferred_end_vel, + const double start_time); + + /** + * Finds the new timestamps for each point along the curve based on the motion + * profile. + */ + std::vector + integrate_constrained_states(std::vector constrainedStates); + + /** + * Finds the ProfilePoint on the profiled curve for the given timestamp. + * + * This with interpolate between points on the curve if a point with an exact + * matching timestamp is not found. + */ + ProfilePoint get_point_at_time(const ControlVector start, + const ControlVector end, + std::vector points, + double t); + + /** + * Linearly interpolates between points along the profiled curve. + */ + ProfilePoint lerp_point(QuinticPolynomial x_qp, + QuinticPolynomial y_qp, + ProfilePoint start, + ProfilePoint end, + double i); + + /** + * Returns the spline curve for the given control vectors and path duration. + */ + QuinticPolynomial get_x_spline(const ControlVector start, + const ControlVector end, + const double duration); + QuinticPolynomial get_y_spline(const ControlVector start, + const ControlVector end, + const double duration); + + /** + * Applies the general constraints and model constraints to the given state. + */ + void enforce_accel_lims(ConstrainedState* state); + + /** + * Imposes the motion profile constraints on a segment of the path from the + * perspective of iterating forwards through the path. + */ + void forward_pass(ConstrainedState* predecessor, ConstrainedState* successor); + + /** + * Imposes the motion profile constraints on a segment of the path from the + * perspective of iterating backwards through the path. + */ + void backward_pass(ConstrainedState* predecessor, + ConstrainedState* successor); + + /** + * Calculates the final velocity for a path segment. + */ + double vf(double vi, double a, double ds); + + /** + * Calculates the initial acceleration needed to match the segments' + * velocities. + */ + double ai(double vf, double vi, double s); + + /** + * Values that are closer to each other than this value are considered equal. + */ + static constexpr double K_EPSILON = 1e-5; +}; +} // namespace squiggles + +#endif diff --git a/include/okapi/squiggles/squiggles.hpp b/include/okapi/squiggles/squiggles.hpp new file mode 100644 index 00000000..86c1bfa9 --- /dev/null +++ b/include/okapi/squiggles/squiggles.hpp @@ -0,0 +1,22 @@ +/** + * Copyright 2020 Jonathan Bayless + * + * Use of this source code is governed by an MIT-style license that can be found + * in the LICENSE file or at https://opensource.org/licenses/MIT. + */ +#ifndef _ROBOT_SQUIGGLES_H_ +#define _ROBOT_SQUIGGLES_H_ + +#include "geometry/controlvector.hpp" +#include "geometry/pose.hpp" +#include "geometry/profilepoint.hpp" + +#include "physicalmodel/passthroughmodel.hpp" +#include "physicalmodel/physicalmodel.hpp" +#include "physicalmodel/tankmodel.hpp" + +#include "constraints.hpp" +#include "io.hpp" +#include "spline.hpp" + +#endif \ No newline at end of file diff --git a/include/pros/adi.h b/include/pros/adi.h index c06176ad..8f0f556f 100644 --- a/include/pros/adi.h +++ b/include/pros/adi.h @@ -8,7 +8,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/adi.hpp b/include/pros/adi.hpp index 6dc99ef5..c2fd258d 100644 --- a/include/pros/adi.hpp +++ b/include/pros/adi.hpp @@ -8,7 +8,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 @@ -494,10 +494,13 @@ class ADIEncoder : private ADIPort { * sensor with the removable cover side up, and the "bottom" wire from * the encoder sensor * \param reverse - * If "true", the sensor will count in theopposite direction + * If "true", the sensor will count in the opposite direction */ ADIEncoder(ext_adi_port_tuple_t port_tuple, bool reversed = false); + // Delete copy constructor to prevent a compilation error from the constructor above. + ADIEncoder(ADIEncoder &) = delete; + /** * Sets the encoder value to zero. * diff --git a/include/pros/api_legacy.h b/include/pros/api_legacy.h index 068f7e8a..deb7d222 100644 --- a/include/pros/api_legacy.h +++ b/include/pros/api_legacy.h @@ -10,7 +10,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/include/pros/apix.h b/include/pros/apix.h index 8e7d3068..876a98c8 100644 --- a/include/pros/apix.h +++ b/include/pros/apix.h @@ -12,7 +12,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/include/pros/distance.h b/include/pros/distance.h index b7feda19..783da8fd 100644 --- a/include/pros/distance.h +++ b/include/pros/distance.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/error.h b/include/pros/error.h index 8485978a..a7e4e54e 100644 --- a/include/pros/error.h +++ b/include/pros/error.h @@ -6,7 +6,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/ext_adi.h b/include/pros/ext_adi.h index 48e79096..f75ee051 100644 --- a/include/pros/ext_adi.h +++ b/include/pros/ext_adi.h @@ -8,7 +8,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/gps.h b/include/pros/gps.h index 1af417bc..1b2e7e7b 100644 --- a/include/pros/gps.h +++ b/include/pros/gps.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/gps.hpp b/include/pros/gps.hpp index 0d8b731c..fce40c2a 100644 --- a/include/pros/gps.hpp +++ b/include/pros/gps.hpp @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/imu.h b/include/pros/imu.h index 59116eee..f5a1cdc3 100644 --- a/include/pros/imu.h +++ b/include/pros/imu.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/imu.hpp b/include/pros/imu.hpp index 84272b0a..99b28c8d 100644 --- a/include/pros/imu.hpp +++ b/include/pros/imu.hpp @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/link.h b/include/pros/link.h index f370b7e3..212834cc 100644 --- a/include/pros/link.h +++ b/include/pros/link.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/link.hpp b/include/pros/link.hpp index d44c6bd5..d6c18f3a 100644 --- a/include/pros/link.hpp +++ b/include/pros/link.hpp @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2021, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/llemu.h b/include/pros/llemu.h index 4cb792b3..8a6d7570 100644 --- a/include/pros/llemu.h +++ b/include/pros/llemu.h @@ -13,7 +13,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/llemu.hpp b/include/pros/llemu.hpp index 8818eddb..a4834e02 100644 --- a/include/pros/llemu.hpp +++ b/include/pros/llemu.hpp @@ -13,7 +13,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/misc.h b/include/pros/misc.h index 0b6c923f..16cba550 100644 --- a/include/pros/misc.h +++ b/include/pros/misc.h @@ -10,7 +10,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reservered. * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/include/pros/misc.hpp b/include/pros/misc.hpp index 2415c2f1..7fcb4b54 100644 --- a/include/pros/misc.hpp +++ b/include/pros/misc.hpp @@ -10,7 +10,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reservered. * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/include/pros/motors.h b/include/pros/motors.h index 51ee02f4..73710924 100644 --- a/include/pros/motors.h +++ b/include/pros/motors.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/motors.hpp b/include/pros/motors.hpp index da330a9c..10925990 100644 --- a/include/pros/motors.hpp +++ b/include/pros/motors.hpp @@ -461,6 +461,7 @@ class Motor { * * \return The motor's voltage in mV or PROS_ERR_F if the operation failed, * setting errno. + * */ virtual std::int32_t get_voltage(void) const; @@ -859,8 +860,11 @@ class Motor { class Motor_Group { public: - explicit Motor_Group(const std::initializer_list motors); - explicit Motor_Group(const std::vector motor_ports); + Motor_Group(const std::initializer_list motors); + explicit Motor_Group(const std::vector& motors); + explicit Motor_Group(const std::initializer_list motor_ports); + explicit Motor_Group(const std::vector motor_ports); // Pass by value to preserve ABI + /****************************************************************************/ /** Motor Group movement functions **/ /** **/ @@ -1014,6 +1018,101 @@ class Motor_Group { * failed, setting errno. */ std::int32_t brake(void); + + /* + * Gets the voltages delivered to the motors 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 + * EACCESS - The Motor group mutex can't be taken or given + * + * \return The voltage of the motor in millivolts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor_Group motors({1, 2}); + * std::vector voltages; + * while (true) { + * voltages = motors.get_voltages(); + * + * for (uint32_t i = 0; i < voltages.size(); i++) { + * printf("Voltages: %ld\n", voltages[i]); + * } + * pros::delay(20); + * } + * } + * \endcode + * + */ + std::vector get_voltages(void); + + /* + * Get the voltage limits of the motors 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 + * EACCESS - The Motor group mutex can't be taken or given + * + * \return The voltage limit of the motor in millivolts or PROS_ERR_F if the operation + * failed, setting errno. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor_Group motors({1, 2}); + * std::vector voltage_limits; + * while (true) { + * voltage_limits = motors.get_voltage_limits(); + * + * for (uint32_t i = 0; i < voltage_limits.size(); i++) { + * printf("Voltage Limits: %ld\n", voltage_limits[i]); + * } + * pros::delay(20); + * } + * } + * \endcode + */ + std::vector get_voltage_limits(void); + + /* + * Gets the raw encoder positions of a motor group 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 + * EACCESS - The Motor group mutex can't be taken or given + * + * \return A vector of the raw encoder positions of the motors in the motor group + * based on the timestamps passed in. If a timestamp is not found for a motor, the + * value at that index will be PROS_ERR. + * + * \b Example + * \code + * void opcontrol() { + * pros::Motor_Group motors({1, 2}); + * std::vector timestamps; + * std::vector positions; + * std::uint32_t temp = 0; + * std::uint32_t temp2 = 0; + * timestamps.push_back(&temp); + * timestamps.push_back(&temp2); + * + * while (true) { + * positions = motors.get_raw_positions(timestamps); + * + * printf("Position: %ld, Time: %ln\n", positions[0], timestamps[0]); + * printf("Position: %ld, Time: %ln\n", positions[1], timestamps[1]); + * + * pros::delay(20); + * } + * } + * \endcode + */ + std::vector get_raw_positions(std::vector ×tamps); /****************************************************************************/ /** Motor configuration functions **/ /** **/ @@ -1036,6 +1135,20 @@ class Motor_Group { pros::Motor& operator[](int i); + /** + * Indexes Motor in the Motor_Group. + * + * This function uses the following values of errno when an error state is + * reached: + * Throws an std::out_of_range error when indexing out of range + * + * \param i + * The index value in the motor group. + * + * \return the appropriate Motor reference. + */ + pros::Motor& at(int i); + /** * Indexes Motor in the Motor_Group in the same way as an array. * @@ -1341,6 +1454,19 @@ class Motor_Group { * E_MOTOR_ENCODER_INVALID if the operation failed. */ std::vector get_encoder_units(void); + + /** + * Gets the encoder units that were set for each motor. + * + * This function uses the following values of errno when an error state is + * reached: + * ENODEV - The port cannot be configured as a motor + * EACCESS - The Motor group mutex can't be taken or given + * + * \return The vector filled with motors' temperature in degrees Celsius or PROS_ERR_F if the + * operation failed, setting errno. + */ + virtual std::vector get_temperatures(void); private: std::vector _motors; diff --git a/include/pros/optical.h b/include/pros/optical.h index c3cace98..9dd1c1b0 100644 --- a/include/pros/optical.h +++ b/include/pros/optical.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 @@ -265,6 +265,39 @@ int32_t optical_enable_gesture(uint8_t port); */ int32_t optical_disable_gesture(uint8_t port); +/** + * Get integration time (update rate) of the optical sensor in milliseconds, with + * minimum time being + * + * 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 an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \return Integration time in milliseconds if the operation is successful + * or PROS_ERR if the operation failed, setting errno. + */ +double optical_get_integration_time(uint8_t port); + +/** + * Set integration time (update rate) of the optical sensor in milliseconds. + * + * 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 an Optical Sensor + * + * \param port + * The V5 Optical Sensor port number from 1-21 + * \param time + * The desired integration time in milliseconds + * \return 1 if the operation is successful or PROS_ERR if the operation failed, + * setting errno. + */ +int32_t optical_set_integration_time(uint8_t port, double time); + #ifdef __cplusplus } } diff --git a/include/pros/optical.hpp b/include/pros/optical.hpp index 783520d4..006108d6 100644 --- a/include/pros/optical.hpp +++ b/include/pros/optical.hpp @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 @@ -41,6 +41,8 @@ class Optical { */ explicit Optical(const std::uint8_t port); + explicit Optical(std::uint8_t port, double time); + /** * Get the detected color hue * @@ -219,6 +221,36 @@ class Optical { */ virtual std::int32_t disable_gesture(); + /** + * Set integration time (update rate) of the optical sensor in milliseconds, with + * minimum time being 3 ms and maximum time being 712 ms. Default is 100 ms, with the + * optical sensor communciating with the V5 brain every 20 ms. + * + * 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 an Optical Sensor + * + * \return 1 if the operation is successful or PROS_ERR_F if the operation failed, + * setting errno. + */ + double get_integration_time(); + + /** + * Get integration time (update rate) of the optical sensor in milliseconds. + * + * 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 an Optical Sensor + * + * \param time + * The desired integration time in milliseconds + * \return Integration time in milliseconds if the operation is successful + * or PROS_ERR if the operation failed, setting errno. + */ + std::int32_t set_integration_time(double time); + /** * Gets the port number of the Optical Sensor. * diff --git a/include/pros/rotation.h b/include/pros/rotation.h index 197936ac..8daf2fd8 100644 --- a/include/pros/rotation.h +++ b/include/pros/rotation.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/rotation.hpp b/include/pros/rotation.hpp index c53ab7b1..a063eda2 100644 --- a/include/pros/rotation.hpp +++ b/include/pros/rotation.hpp @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/rtos.h b/include/pros/rtos.h index 3afdb24a..c0767342 100644 --- a/include/pros/rtos.h +++ b/include/pros/rtos.h @@ -10,7 +10,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/include/pros/rtos.hpp b/include/pros/rtos.hpp index 0cd0d6c6..2505f1d1 100644 --- a/include/pros/rtos.hpp +++ b/include/pros/rtos.hpp @@ -10,7 +10,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/include/pros/screen.h b/include/pros/screen.h index 4cffe76c..8076daa9 100644 --- a/include/pros/screen.h +++ b/include/pros/screen.h @@ -5,7 +5,7 @@ * * Contains user calls to the v5 screen for touching and displaying graphics. * - * \copyright (c) 2017-2021, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/screen.hpp b/include/pros/screen.hpp index 3aecd188..d7f6c08e 100644 --- a/include/pros/screen.hpp +++ b/include/pros/screen.hpp @@ -5,7 +5,7 @@ * * Contains user calls to the v5 screen for touching and displaying graphics. * - * \copyright (c) 2017, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/serial.h b/include/pros/serial.h index 6db69cd0..357aa107 100644 --- a/include/pros/serial.h +++ b/include/pros/serial.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \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 diff --git a/include/pros/vision.h b/include/pros/vision.h index 8464b6c3..33918c78 100644 --- a/include/pros/vision.h +++ b/include/pros/vision.h @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/include/pros/vision.hpp b/include/pros/vision.hpp index eeb00462..e40af9b8 100644 --- a/include/pros/vision.hpp +++ b/include/pros/vision.hpp @@ -9,7 +9,7 @@ * This file should not be modified by users, since it gets replaced whenever * a kernel upgrade occurs. * - * Copyright (c) 2017-2022, Purdue University ACM SIGBots. + * \copyright Copyright (c) 2017-2023, Purdue University ACM SIGBots. * All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/project.pros b/project.pros index df6fe443..a49c8e68 100644 --- a/project.pros +++ b/project.pros @@ -5,7 +5,7 @@ "target": "v5", "templates": { "kernel": { - "location": "C:\\Users\\cicad\\AppData\\Roaming\\PROS\\templates\\kernel@3.7.3", + "location": "C:\\Users\\xuzwi\\AppData\\Roaming\\PROS\\templates\\kernel@3.8.0", "metadata": { "cold_addr": "58720256", "cold_output": "bin/cold.package.bin", @@ -18,295 +18,294 @@ "py/object": "pros.conductor.templates.local_template.LocalTemplate", "supported_kernels": null, "system_files": [ - "common.mk", - "include/display/lv_objx/lv_tileview.h", - "firmware/libm.a", - "include/display/lv_hal/lv_hal_indev.h", - "include/display/lv_objx/lv_bar.h", - "include/pros/ext_adi.h", - "include/display/lv_fonts/lv_font_builtin.h", - "include/display/lv_draw/lv_draw_rect.h", - "include/display/lv_misc/lv_anim.h", - "include/display/lv_misc/lv_font.h", + "include/display/lv_core/lv_vdb.h", + "include/display/lv_core/lv_core.mk", + "include/display/lv_misc/lv_math.h", + "include/display/lv_objx/lv_tabview.h", "include/display/lv_misc/lv_color.h", - "include/display/lv_themes/lv_theme_zen.h", + "include/display/lv_hal/lv_hal_indev.h", + "include/display/lv_fonts/lv_fonts.mk", "include/display/lv_misc/lv_symbol_def.h", - "include/display/lv_objx/lv_cb.h", - "include/pros/misc.h", - "include/display/lv_misc/lv_task.h", - "include/display/lv_core/lv_obj.h", - "include/display/lv_themes/lv_themes.mk", - "include/pros/adi.hpp", - "include/display/lv_objx/lv_line.h", - "include/display/lv_objx/lv_gauge.h", - "include/display/lv_objx/lv_arc.h", - "include/display/lv_core/lv_lang.h", - "include/pros/colors.h", - "include/display/lv_objx/lv_ta.h", - "include/pros/gps.h", - "include/display/lv_objx/lv_lmeter.h", - "include/pros/optical.h", - "include/pros/screen.hpp", "include/display/lv_hal/lv_hal.mk", - "include/pros/serial.h", - "include/pros/link.h", - "include/display/lv_hal/lv_hal.h", - "include/display/lv_objx/lv_btnm.h", - "include/display/lv_objx/lv_img.h", - "include/display/lv_objx/lv_label.h", - "include/display/lv_misc/lv_gc.h", - "include/display/lvgl.h", - "include/pros/adi.h", + "include/display/lv_themes/lv_theme_night.h", + "include/display/lv_draw/lv_draw_triangle.h", "include/pros/optical.hpp", - "include/display/lv_objx/lv_sw.h", - "include/api.h", - "include/pros/llemu.hpp", - "include/display/lv_core/lv_style.h", - "include/pros/colors.hpp", - "firmware/v5.ld", "include/display/lv_draw/lv_draw_vbasic.h", - "include/display/lv_misc/lv_fs.h", - "include/display/lv_objx/lv_page.h", - "include/display/lv_draw/lv_draw.mk", - "include/display/lv_objx/lv_calendar.h", - "include/display/lv_objx/lv_win.h", - "include/pros/rtos.h", - "include/display/lv_conf_checker.h", - "include/display/lv_themes/lv_theme_night.h", - "include/display/lv_objx/lv_cont.h", - "include/display/licence.txt", - "include/pros/api_legacy.h", - "include/display/lv_misc/lv_log.h", - "firmware/libc.a", - "include/pros/rtos.hpp", - "include/display/lv_objx/lv_roller.h", - "include/display/lv_draw/lv_draw_label.h", + "include/display/lv_objx/lv_objx_templ.h", + "include/display/lv_core/lv_refr.h", + "include/pros/link.hpp", + "include/display/lv_objx/lv_btnm.h", + "include/display/lv_objx/lv_cb.h", + "firmware/v5-common.ld", + "include/pros/ext_adi.h", + "include/pros/rotation.h", "include/display/lv_objx/lv_spinbox.h", - "include/display/lv_misc/lv_mem.h", - "include/display/lv_objx/lv_led.h", - "include/display/lv_objx/lv_canvas.h", "include/display/lv_misc/lv_circ.h", - "include/pros/screen.h", - "include/pros/apix.h", - "include/display/lv_objx/lv_objx.mk", - "include/display/lv_misc/lv_txt.h", - "include/display/lv_draw/lv_draw_line.h", - "include/display/lv_draw/lv_draw.h", - "include/display/lv_objx/lv_preload.h", - "include/display/lv_themes/lv_theme_material.h", - "include/pros/distance.hpp", - "include/pros/rotation.hpp", - "include/display/lv_themes/lv_theme.h", - "include/display/lv_misc/lv_area.h", - "firmware/libpros.a", - "include/pros/motors.hpp", - "include/display/lv_misc/lv_ufs.h", - "include/display/lv_misc/lv_math.h", + "include/display/lv_misc/lv_mem.h", + "include/display/lv_objx/lv_page.h", + "include/display/lv_objx/lv_ddlist.h", "include/display/lv_core/lv_group.h", + "include/display/lvgl.h", "include/display/lv_objx/lv_chart.h", - "include/display/lv_objx/lv_slider.h", - "include/display/lv_draw/lv_draw_triangle.h", - "include/display/lv_objx/lv_mbox.h", - "include/display/lv_hal/lv_hal_disp.h", - "include/pros/misc.hpp", + "include/pros/distance.h", "include/display/lv_objx/lv_list.h", - "include/pros/serial.hpp", - "include/display/lv_objx/lv_imgbtn.h", "include/pros/vision.h", - "include/display/lv_objx/lv_objx_templ.h", - "firmware/v5-hot.ld", - "include/display/lv_core/lv_indev.h", + "include/pros/misc.hpp", + "include/display/lv_draw/lv_draw.h", + "include/display/lv_objx/lv_label.h", + "include/display/lv_misc/lv_font.h", + "include/display/lv_draw/lv_draw_img.h", + "include/display/lv_misc/lv_log.h", + "include/display/lv_misc/lv_templ.h", "include/pros/llemu.h", - "include/pros/imu.h", - "include/display/README.md", - "include/pros/rotation.h", - "include/display/lv_version.h", + "include/display/lv_objx/lv_btn.h", + "include/display/lv_fonts/lv_font_builtin.h", + "include/display/lv_objx/lv_calendar.h", + "firmware/libm.a", + "include/display/lv_conf.h", + "include/display/lv_objx/lv_sw.h", + "include/display/lv_draw/lv_draw_rect.h", + "include/display/lv_objx/lv_cont.h", "include/pros/vision.hpp", - "include/display/lv_themes/lv_theme_nemo.h", - "include/display/lv_core/lv_vdb.h", - "include/display/lv_objx/lv_ddlist.h", - "include/display/lv_core/lv_core.mk", + "include/display/lv_objx/lv_mbox.h", + "include/pros/adi.hpp", "include/pros/imu.hpp", - "include/display/lv_misc/lv_ll.h", - "include/display/lv_draw/lv_draw_rbasic.h", - "include/display/lv_themes/lv_theme_mono.h", - "include/display/lv_fonts/lv_fonts.mk", - "include/display/lv_misc/lv_templ.h", + "include/display/lv_objx/lv_table.h", + "include/pros/screen.hpp", + "include/display/lv_draw/lv_draw_label.h", + "include/display/lv_misc/lv_txt.h", + "include/pros/api_legacy.h", + "include/display/lv_objx/lv_lmeter.h", "include/display/lv_themes/lv_theme_templ.h", - "include/display/lv_themes/lv_theme_default.h", - "include/display/lv_objx/lv_btn.h", - "include/display/lv_conf.h", - "include/display/lv_core/lv_refr.h", + "include/pros/apix.h", + "include/display/lv_draw/lv_draw.mk", + "include/display/lv_themes/lv_theme_alien.h", + "include/pros/colors.hpp", + "include/display/lv_objx/lv_img.h", + "firmware/libc.a", + "include/display/lv_themes/lv_theme_zen.h", + "include/display/lv_themes/lv_theme_material.h", + "include/display/lv_draw/lv_draw_arc.h", + "include/display/lv_themes/lv_theme_mono.h", + "include/display/lv_themes/lv_themes.mk", + "include/display/lv_objx/lv_slider.h", + "include/pros/serial.h", + "include/display/lv_themes/lv_theme.h", + "include/display/README.md", + "include/display/lv_objx/lv_canvas.h", + "include/pros/misc.h", + "include/display/lv_misc/lv_fs.h", + "include/pros/rtos.h", + "include/display/lv_core/lv_indev.h", + "include/pros/motors.hpp", + "include/display/lv_core/lv_style.h", + "include/display/lv_version.h", + "include/display/lv_core/lv_lang.h", + "include/api.h", + "include/display/lv_objx/lv_gauge.h", + "include/pros/rtos.hpp", + "include/display/lv_hal/lv_hal_disp.h", "include/pros/motors.h", - "include/display/lv_objx/lv_tabview.h", + "include/display/lv_objx/lv_led.h", + "include/display/lv_draw/lv_draw_rbasic.h", + "include/display/lv_objx/lv_kb.h", + "include/display/lv_conf_checker.h", + "include/display/lv_hal/lv_hal.h", + "include/display/lv_draw/lv_draw_line.h", "include/pros/gps.hpp", - "include/display/lv_hal/lv_hal_tick.h", + "include/display/lv_objx/lv_objx.mk", + "include/display/lv_objx/lv_win.h", + "include/display/lv_core/lv_obj.h", + "include/display/lv_objx/lv_arc.h", + "include/pros/link.h", + "include/display/lv_objx/lv_preload.h", + "include/display/lv_misc/lv_area.h", + "include/display/lv_misc/lv_ll.h", + "include/pros/optical.h", + "include/pros/serial.hpp", + "include/pros/screen.h", + "include/display/lv_themes/lv_theme_nemo.h", + "include/pros/llemu.hpp", + "firmware/libpros.a", + "include/display/lv_misc/lv_gc.h", + "include/display/lv_misc/lv_anim.h", + "include/display/lv_objx/lv_line.h", + "include/pros/distance.hpp", + "include/pros/rotation.hpp", "include/pros/error.h", - "firmware/v5-common.ld", - "include/display/lv_draw/lv_draw_arc.h", - "include/display/lv_themes/lv_theme_alien.h", - "include/pros/distance.h", - "include/display/lv_objx/lv_table.h", + "include/display/lv_objx/lv_tileview.h", + "include/pros/gps.h", + "include/display/lv_misc/lv_task.h", + "include/pros/imu.h", + "firmware/v5-hot.ld", "include/display/lv_misc/lv_misc.mk", - "include/display/lv_draw/lv_draw_img.h", - "include/display/lv_objx/lv_kb.h", - "include/pros/link.hpp" + "include/pros/colors.h", + "common.mk", + "include/display/lv_objx/lv_roller.h", + "include/display/lv_objx/lv_bar.h", + "include/display/lv_themes/lv_theme_default.h", + "firmware/v5.ld", + "include/display/lv_misc/lv_ufs.h", + "include/display/lv_hal/lv_hal_tick.h", + "include/display/licence.txt", + "include/display/lv_objx/lv_ta.h", + "include/display/lv_objx/lv_imgbtn.h", + "include/pros/adi.h" ], "target": "v5", "user_files": [ + "src/main.cc", ".gitignore", - "include/main.h", "Makefile", - "src/main.cc", - "include/main.hpp", - "src/main.c", "src/main.cpp", - "include/main.hh" + "src/main.c", + "include/main.hpp", + "include/main.hh", + "include/main.h" ], - "version": "3.7.3" + "version": "3.8.0" }, "okapilib": { - "location": "C:\\Users\\union\\AppData\\Roaming\\PROS\\templates\\okapilib@4.2.0", + "location": "C:\\Users\\xuzwi\\AppData\\Roaming\\PROS\\templates\\okapilib@4.8.0", "metadata": { - "allow_online": true, - "force_apply": false, - "kernel_version": "3.5.2", "origin": "pros-mainline" }, "name": "okapilib", "py/object": "pros.conductor.templates.local_template.LocalTemplate", "supported_kernels": "^3.3.1", "system_files": [ - "include/okapi/impl/filter/velMathFactory.hpp", - "include/okapi/api/odometry/twoEncoderOdometry.hpp", - "include/okapi/api/control/util/pathfinderUtil.hpp", - "include/okapi/impl/device/rotarysensor/adiGyro.hpp", - "include/okapi/pathfinder/include/pathfinder/spline.h", - "include/okapi/api/units/QAngularAcceleration.hpp", - "include/okapi/pathfinder/include/pathfinder/trajectory.h", - "include/okapi/api/control/iterative/iterativePosPidController.hpp", - "include/okapi/pathfinder/include/pathfinder/io.h", - "include/okapi/api/control/async/asyncController.hpp", - "include/okapi/api/util/timeUtil.hpp", - "include/okapi/api/control/async/asyncVelocityController.hpp", - "include/okapi/pathfinder/include/pathfinder/fit.h", - "include/okapi/api/filter/medianFilter.hpp", - "include/okapi/api/chassis/model/threeEncoderSkidSteerModel.hpp", - "include/okapi/api/device/motor/abstractMotor.hpp", - "include/okapi/pathfinder/include/pathfinder/structs.h", - "include/okapi/api/units/QAngle.hpp", + "include/okapi/api/odometry/odomMath.hpp", + "include/okapi/squiggles/physicalmodel/physicalmodel.hpp", + "include/okapi/api/chassis/model/threeEncoderXDriveModel.hpp", + "include/okapi/api/chassis/model/hDriveModel.hpp", + "include/okapi/api/chassis/model/readOnlyChassisModel.hpp", + "include/okapi/api/device/button/buttonBase.hpp", + "include/okapi/api/units/QAngularJerk.hpp", + "include/okapi/api/control/iterative/iterativeController.hpp", + "include/okapi/api/control/controllerInput.hpp", + "include/okapi/squiggles/math/quinticpolynomial.hpp", + "include/okapi/api/device/rotarysensor/continuousRotarySensor.hpp", "include/okapi/api/control/async/asyncPositionController.hpp", - "include/okapi/pathfinder/include/pathfinder/lib.h", - "include/okapi/impl/control/iterative/iterativeControllerFactory.hpp", - "include/okapi/impl/device/rotarysensor/IMU.hpp", - "include/okapi/pathfinder/include/pathfinder/followers/encoder.h", - "include/okapi/impl/control/async/asyncVelControllerBuilder.hpp", - "include/okapi/api/control/util/pidTuner.hpp", - "include/okapi/api/units/QAcceleration.hpp", - "include/okapi/impl/device/motor/adiMotor.hpp", - "include/okapi/impl/util/rate.hpp", - "include/okapi/api/filter/velMath.hpp", - "include/okapi/api.hpp", - "include/okapi/api/units/QJerk.hpp", - "include/okapi/api/odometry/stateMode.hpp", - "include/okapi/api/util/mathUtil.hpp", - "include/okapi/api/control/async/asyncVelPidController.hpp", - "include/okapi/impl/control/async/asyncMotionProfileControllerBuilder.hpp", - "include/okapi/api/units/QLength.hpp", - "include/okapi/pathfinder/include/pathfinder/followers/distance.h", - "include/okapi/api/chassis/controller/defaultOdomChassisController.hpp", - "include/okapi/api/util/logging.hpp", - "include/okapi/pathfinder/include/pathfinder/modifiers/tank.h", - "include/okapi/api/odometry/odomState.hpp", + "include/okapi/api/filter/passthroughFilter.hpp", "include/okapi/api/device/rotarysensor/rotarySensor.hpp", - "include/okapi/api/device/rotarysensor/continuousRotarySensor.hpp", - "include/okapi/api/chassis/controller/chassisScales.hpp", + "include/okapi/api/odometry/stateMode.hpp", + "include/okapi/impl/device/controller.hpp", "include/okapi/api/units/QTime.hpp", - "include/okapi/api/control/async/asyncLinearMotionProfileController.hpp", + "include/okapi/api/control/util/controllerRunner.hpp", "include/okapi/api/units/QTorque.hpp", + "include/okapi/impl/device/rotarysensor/IMU.hpp", + "include/okapi/api/control/util/pidTuner.hpp", + "include/okapi/impl/util/timeUtilFactory.hpp", + "include/okapi/api/device/motor/abstractMotor.hpp", + "include/okapi/impl/device/button/controllerButton.hpp", + "include/okapi/impl/device/rotarysensor/integratedEncoder.hpp", + "include/okapi/impl/device/rotarysensor/adiEncoder.hpp", + "include/okapi/api/filter/composableFilter.hpp", + "include/okapi/api/chassis/model/xDriveModel.hpp", + "include/okapi/squiggles/geometry/pose.hpp", + "include/okapi/api/odometry/twoEncoderOdometry.hpp", + "include/okapi/api/util/timeUtil.hpp", + "firmware/squiggles.mk", + "include/okapi/api/control/async/asyncPosPidController.hpp", + "include/okapi/impl/control/util/controllerRunnerFactory.hpp", + "include/okapi/impl/chassis/controller/chassisControllerBuilder.hpp", + "include/okapi/api/control/closedLoopController.hpp", + "include/okapi/squiggles/math/utils.hpp", + "include/okapi/api/control/async/asyncVelIntegratedController.hpp", + "include/okapi/api/units/QLength.hpp", + "include/okapi/impl/device/motor/motor.hpp", + "include/okapi/api/odometry/odometry.hpp", + "include/okapi/api/units/RQuantity.hpp", + "include/okapi/api/units/QArea.hpp", + "include/okapi/api/filter/filter.hpp", "include/okapi/api/device/button/abstractButton.hpp", - "include/okapi/impl/util/configurableTimeUtilFactory.hpp", - "include/okapi/impl/device/button/adiButton.hpp", - "include/okapi/api/chassis/controller/chassisControllerIntegrated.hpp", - "include/okapi/api/control/iterative/iterativeMotorVelocityController.hpp", + "include/okapi/api/units/QPressure.hpp", + "include/okapi/api/control/async/asyncLinearMotionProfileController.hpp", + "include/okapi/api/control/util/flywheelSimulator.hpp", + "include/okapi/api/util/logging.hpp", + "include/okapi/api/chassis/model/threeEncoderSkidSteerModel.hpp", "include/okapi/api/filter/emaFilter.hpp", - "include/okapi/api/util/abstractRate.hpp", - "firmware/okapilib.a", - "include/okapi/api/chassis/model/skidSteerModel.hpp", - "include/okapi/impl/control/util/pidTunerFactory.hpp", - "include/okapi/api/units/QSpeed.hpp", - "include/okapi/api/units/QAngularJerk.hpp", - "include/okapi/api/chassis/model/chassisModel.hpp", - "include/okapi/api/control/offsettableControllerInput.hpp", - "include/okapi/api/units/QArea.hpp", - "include/okapi/api/filter/filteredControllerInput.hpp", + "include/okapi/impl/device/controllerUtil.hpp", + "include/okapi/api/util/mathUtil.hpp", + "include/okapi/api/filter/averageFilter.hpp", "include/okapi/api/control/iterative/iterativeVelocityController.hpp", - "include/okapi/impl/util/timer.hpp", - "include/okapi/pathfinder/include/pathfinder/mathutil.h", - "include/okapi/impl/device/distanceSensor.hpp", + "include/okapi/api/odometry/point.hpp", + "include/okapi/api/control/async/asyncController.hpp", + "include/okapi/impl/control/async/asyncMotionProfileControllerBuilder.hpp", "include/okapi/api/coreProsAPI.hpp", - "include/okapi/api/control/async/asyncPosPidController.hpp", - "include/okapi/api/chassis/controller/chassisController.hpp", - "include/okapi/api/control/async/asyncVelIntegratedController.hpp", - "include/okapi/api/control/closedLoopController.hpp", - "include/okapi/api/filter/composableFilter.hpp", - "include/okapi/api/chassis/controller/chassisControllerPid.hpp", - "include/okapi/impl/control/util/controllerRunnerFactory.hpp", + "include/okapi/api/units/QSpeed.hpp", + "include/okapi/impl/control/util/pidTunerFactory.hpp", + "include/okapi/api/units/QAngle.hpp", + "include/okapi/api/control/async/asyncVelocityController.hpp", "include/okapi/api/odometry/threeEncoderOdometry.hpp", - "include/okapi/impl/device/opticalSensor.hpp", - "include/okapi/api/chassis/model/readOnlyChassisModel.hpp", - "include/okapi/api/units/QMass.hpp", - "include/okapi/impl/device/rotarysensor/integratedEncoder.hpp", - "include/okapi/api/filter/demaFilter.hpp", - "include/okapi/impl/util/timeUtilFactory.hpp", - "include/okapi/impl/device/motor/motor.hpp", + "include/okapi/api/filter/velMath.hpp", "include/okapi/api/control/async/asyncPosIntegratedController.hpp", - "include/okapi/api/odometry/odometry.hpp", - "include/okapi/api/control/iterative/iterativeVelPidController.hpp", - "include/okapi/impl/chassis/controller/chassisControllerBuilder.hpp", - "include/okapi/api/odometry/point.hpp", - "include/okapi/api/control/util/controllerRunner.hpp", - "include/okapi/api/chassis/model/hDriveModel.hpp", - "include/okapi/api/control/async/asyncMotionProfileController.hpp", - "include/okapi/api/control/async/asyncWrapper.hpp", - "include/okapi/impl/device/controller.hpp", - "include/okapi/api/control/iterative/iterativeController.hpp", - "include/okapi/api/units/QFrequency.hpp", - "include/okapi/api/device/button/buttonBase.hpp", + "include/okapi/squiggles/constraints.hpp", + "include/okapi/api/filter/filteredControllerInput.hpp", + "include/okapi/api/chassis/controller/chassisControllerPid.hpp", "include/okapi/api/control/iterative/iterativePositionController.hpp", - "include/okapi/pathfinder/include/pathfinder/modifiers/swerve.h", - "include/okapi/api/filter/filter.hpp", - "include/okapi/api/odometry/odomMath.hpp", - "include/okapi/impl/device/rotarysensor/adiEncoder.hpp", - "include/okapi/api/util/abstractTimer.hpp", + "include/okapi/api/control/offsettableControllerInput.hpp", + "include/okapi/squiggles/squiggles.hpp", + "include/okapi/api/units/QAngularSpeed.hpp", + "include/okapi/api/control/iterative/iterativePosPidController.hpp", + "include/okapi/squiggles/physicalmodel/tankmodel.hpp", + "include/okapi/impl/util/rate.hpp", + "include/okapi/api/filter/medianFilter.hpp", "include/okapi/impl/device/rotarysensor/potentiometer.hpp", - "include/okapi/impl/device/button/controllerButton.hpp", + "include/okapi/api/control/iterative/iterativeVelPidController.hpp", + "include/okapi/squiggles/geometry/profilepoint.hpp", + "include/okapi/impl/device/button/adiButton.hpp", + "include/okapi/impl/control/async/asyncVelControllerBuilder.hpp", + "include/okapi/api/filter/demaFilter.hpp", + "include/okapi/api/units/RQuantityName.hpp", + "include/okapi/api/control/util/pathfinderUtil.hpp", + "include/okapi/api/util/abstractTimer.hpp", + "include/okapi/api.hpp", + "include/okapi/impl/control/async/asyncPosControllerBuilder.hpp", + "include/okapi/api/chassis/controller/chassisScales.hpp", + "include/okapi/api/units/QMass.hpp", + "include/okapi/impl/device/rotarysensor/adiGyro.hpp", + "include/okapi/impl/util/configurableTimeUtilFactory.hpp", + "include/okapi/api/control/util/settledUtil.hpp", + "include/okapi/impl/control/iterative/iterativeControllerFactory.hpp", + "include/okapi/impl/util/timer.hpp", + "include/okapi/api/chassis/controller/defaultOdomChassisController.hpp", + "include/okapi/impl/device/motor/motorGroup.hpp", + "include/okapi/api/control/async/asyncWrapper.hpp", + "include/okapi/squiggles/io.hpp", "include/okapi/api/filter/ekfFilter.hpp", - "include/okapi/api/util/supplier.hpp", - "include/okapi/api/units/RQuantity.hpp", - "include/okapi/api/units/QForce.hpp", + "include/okapi/api/control/async/asyncMotionProfileController.hpp", + "include/okapi/squiggles/geometry/controlvector.hpp", + "include/okapi/impl/device/distanceSensor.hpp", "include/okapi/api/control/controllerOutput.hpp", - "include/okapi/impl/device/adiUltrasonic.hpp", "include/okapi/api/units/QVolume.hpp", - "include/okapi/pathfinder/include/pathfinder.h", - "include/okapi/api/filter/passthroughFilter.hpp", - "include/okapi/api/control/controllerInput.hpp", - "include/okapi/impl/device/controllerUtil.hpp", - "include/okapi/api/chassis/model/threeEncoderXDriveModel.hpp", - "include/okapi/api/control/util/flywheelSimulator.hpp", - "include/okapi/api/filter/averageFilter.hpp", - "include/okapi/api/units/QPressure.hpp", - "include/okapi/impl/control/async/asyncPosControllerBuilder.hpp", - "include/okapi/api/units/QAngularSpeed.hpp", - "include/okapi/impl/device/motor/motorGroup.hpp", + "include/okapi/squiggles/spline.hpp", + "include/okapi/api/units/QJerk.hpp", + "include/okapi/api/chassis/controller/chassisController.hpp", + "include/okapi/squiggles/physicalmodel/passthroughmodel.hpp", + "include/okapi/api/units/QAngularAcceleration.hpp", + "include/okapi/api/chassis/controller/chassisControllerIntegrated.hpp", + "include/okapi/impl/device/adiUltrasonic.hpp", + "include/okapi/impl/device/opticalSensor.hpp", + "include/okapi/api/units/QForce.hpp", + "include/okapi/api/util/supplier.hpp", "include/okapi/api/chassis/controller/odomChassisController.hpp", - "include/okapi/api/chassis/model/xDriveModel.hpp", - "include/okapi/api/control/util/settledUtil.hpp", - "include/okapi/impl/device/rotarysensor/rotationSensor.hpp" + "include/okapi/impl/filter/velMathFactory.hpp", + "include/okapi/api/control/iterative/iterativeMotorVelocityController.hpp", + "include/okapi/api/control/async/asyncVelPidController.hpp", + "include/okapi/api/odometry/odomState.hpp", + "include/okapi/api/chassis/model/chassisModel.hpp", + "include/okapi/api/units/QFrequency.hpp", + "include/okapi/impl/device/rotarysensor/rotationSensor.hpp", + "include/okapi/api/util/abstractRate.hpp", + "include/okapi/impl/device/motor/adiMotor.hpp", + "include/okapi/api/units/QAcceleration.hpp", + "include/okapi/api/chassis/model/skidSteerModel.hpp", + "firmware/okapilib.a" ], "target": "v5", "user_files": [], - "version": "4.2.0" + "version": "4.8.0" } }, "upload_options": { diff --git a/src/EZ-Template/util.cpp b/src/EZ-Template/util.cpp index f064f4ac..a0b5da73 100644 --- a/src/EZ-Template/util.cpp +++ b/src/EZ-Template/util.cpp @@ -25,7 +25,7 @@ void print_ez_template() { |_| )" << '\n'; - printf("Version: 2.1.1\n"); + printf("Version: 2.2.0\n"); } std::string get_last_word(std::string text) { std::string word = ""; diff --git a/version b/version index 7c327287..ccbccc3d 100644 --- a/version +++ b/version @@ -1 +1 @@ -2.1.1 \ No newline at end of file +2.2.0 diff --git a/website/docs/Releases/2.2.0.md b/website/docs/Releases/2.2.0.md new file mode 100644 index 00000000..d8fe5959 --- /dev/null +++ b/website/docs/Releases/2.2.0.md @@ -0,0 +1,40 @@ +--- +layout: default +title: Template 2.2.0 +nav_order: 3 +has_children: false +parent: Releases +--- + +## Table of contents +{: .no_toc .text-delta } + +1. TOC +{:toc} + + +--- + +## EZ-Template 2.2.0 Release +Minor release brings in minor features and bugfixes, as well as 2 kernel updates. + +## Changelog +See our [release page](https://github.com/EZ-Robotics/EZ-Template/releases/tag/v2.2.0) for a changelog. + +## Download and Installation +1) Download the latest example project [here](https://github.com/EZ-Robotics/EZ-Template/releases/latest) called `Example Project.zip`. Extract the zip, and open it in PROS. +2) In `src/main.cpp`, configure drive and IMU ports to what they are on your robot. Be sure to read the comments! +3) Configure your wheel size and cartridge. Remember that 4" omni wheels are actually 4.125! +4) In `src/main.cpp`, at the bottom in `void opcontrol()`, decide how you'd like to control your robot! Any flavor of arcade or tank! +5) Turn the robot on and use it in driver control. Make sure the ports are correct and reversed correctly! +6) To test the test autonomous modes, plug into a competition switch and select the autonomous mode on the brain screen by pressing the left and right buttons! The current page will be the autonomous that runs. For making new autonomous routines, check `src/autons.cpp` for examples on how to use the drive functions. + +## Upgrade Existing Project +*Note: this only works for 2.0.0 and beyond. You cannot upgrade from 1.X.X to 2.X.X.* +1) Download the most recent EZ-Template [here](https://github.com/EZ-Robotics/EZ-Template/releases/latest). +2) Move the file to your project. +3) Open terminal or command prompt, and `cd` into your projects directory. +4) Run this command from terminal `prosv5 c fetch EZ-Template@2.2.0.zip`. +5) Apply the library to the project `prosv5 c apply EZ-Template`. +6) Put `#include "EZ-Template/api.hpp"` in your `include/main.h`. +