mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[examples] Clean up examples (#8674)
Move various "examples" into snippets. Several examples that were less than a full mechanism or robot were moved to snippets. `arcadedrive` and `tankdrive` were removed in favor of their Gamepad variants. `hidrumble` was removed due to being too simple. `potentiometerpid` was removed because of low utility. `gyromecanum` replaced `mecanumdrive` for deduplication and because very few teams run holonomic drivetrains without gyros.
This commit is contained in:
@@ -75,6 +75,35 @@ foreach(snippet ${SNIPPETS})
|
||||
add_executable(snippet${snippet} ${sources})
|
||||
wpilib_target_warnings(snippet${snippet})
|
||||
target_include_directories(snippet${snippet} PUBLIC src/main/cpp/snippets/${snippet}/include)
|
||||
target_link_libraries(snippet${snippet} wpilibc commandsv2 romiVendordep xrpVendordep)
|
||||
target_link_libraries(
|
||||
snippet${snippet}
|
||||
apriltag
|
||||
wpilibc
|
||||
commandsv2
|
||||
romiVendordep
|
||||
xrpVendordep
|
||||
)
|
||||
add_dependencies(wpilibcExamples_snippets snippet${snippet})
|
||||
|
||||
if(WITH_TESTS AND EXISTS ${CMAKE_SOURCE_DIR}/wpilibcExamples/src/test/cpp/snippets/${snippet})
|
||||
wpilib_add_test(Snippet_${snippet} src/test/cpp/snippets/${snippet}/cpp)
|
||||
target_sources(Snippet_${snippet}_test PRIVATE ${sources})
|
||||
target_include_directories(
|
||||
Snippet_${snippet}_test
|
||||
PRIVATE
|
||||
src/main/cpp/snippets/${snippet}/include
|
||||
src/test/cpp/snippets/${snippet}/include
|
||||
)
|
||||
target_compile_definitions(Snippet_${snippet}_test PUBLIC RUNNING_WPILIB_TESTS)
|
||||
target_link_libraries(
|
||||
Snippet_${snippet}_test
|
||||
apriltag
|
||||
wpilibc
|
||||
commandsv2
|
||||
romiVendordep
|
||||
xrpVendordep
|
||||
googletest
|
||||
)
|
||||
add_dependencies(wpilibcExamples_test Snippet_${snippet}_test)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@@ -273,7 +273,7 @@ model {
|
||||
if (testFolder.exists()) {
|
||||
"snippets${key}Test"(GoogleTestTestSuiteSpec) {
|
||||
for (NativeComponentSpec c : $.components) {
|
||||
if (c.name == key) {
|
||||
if (c.name == "snippets${key}") {
|
||||
testing c
|
||||
break
|
||||
}
|
||||
@@ -281,20 +281,20 @@ model {
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs "src/test/cpp/examples/${key}/cpp"
|
||||
srcDirs "src/test/cpp/snippets/${key}/cpp"
|
||||
include '**/*.cpp'
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs "src/test/cpp/examples/${key}/include"
|
||||
srcDirs "src/test/cpp/snippets/${key}/include"
|
||||
}
|
||||
}
|
||||
c {
|
||||
source {
|
||||
srcDirs "src/test/cpp/examples/${key}/c"
|
||||
srcDirs "src/test/cpp/snippets/${key}/c"
|
||||
include '**/*.c'
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs "src/test/cpp/examples/${key}/include"
|
||||
srcDirs "src/test/cpp/snippets/${key}/include"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files")
|
||||
load("@rules_pkg//:pkg.bzl", "pkg_zip")
|
||||
load("//wpilibcExamples:example_projects.bzl", "COMMANDS_V2_FOLDERS", "EXAMPLE_FOLDERS", "SNIPPETS_FOLDERS", "TEMPLATES_FOLDERS", "TESTS_FOLDERS")
|
||||
load("//wpilibcExamples:example_projects.bzl", "COMMANDS_V2_FOLDERS", "EXAMPLE_FOLDERS", "EXAMPLE_TESTS_FOLDERS", "SNIPPET_FOLDERS", "SNIPPET_TESTS_FOLDERS", "TEMPLATE_FOLDERS")
|
||||
|
||||
def _package_type(package_type):
|
||||
pkg_files(
|
||||
@@ -40,11 +40,10 @@ def build_examples(halsim_deps = []):
|
||||
name = folder + "-example",
|
||||
srcs = native.glob(["src/main/cpp/examples/" + folder + "/cpp/**/*.cpp", "src/main/cpp/examples/" + folder + "/c/**/*.c"], allow_empty = True),
|
||||
deps = [
|
||||
"//commandsv2",
|
||||
"//apriltag",
|
||||
"//commandsv2",
|
||||
"//romiVendordep",
|
||||
"//xrpVendordep",
|
||||
"//cameraserver",
|
||||
":{}-examples-headers".format(folder),
|
||||
],
|
||||
tags = ["wpi-example"],
|
||||
@@ -68,13 +67,21 @@ def build_commands():
|
||||
def build_snippets():
|
||||
_package_type("snippets")
|
||||
|
||||
for folder in SNIPPETS_FOLDERS:
|
||||
for folder in SNIPPET_FOLDERS:
|
||||
cc_library(
|
||||
name = folder + "-template",
|
||||
name = folder + "-snippets-headers",
|
||||
hdrs = native.glob(["src/main/cpp/snippets/" + folder + "/include/**/*.hpp"], allow_empty = True),
|
||||
strip_include_prefix = "src/main/cpp/snippets/" + folder + "/include",
|
||||
tags = ["wpi-example"],
|
||||
)
|
||||
cc_library(
|
||||
name = folder + "-snippet",
|
||||
srcs = native.glob(["src/main/cpp/snippets/" + folder + "/**/*.cpp"]),
|
||||
hdrs = native.glob(["src/main/cpp/snippets/" + folder + "/**/*.hpp"], allow_empty = True),
|
||||
deps = [
|
||||
"//apriltag",
|
||||
"//commandsv2",
|
||||
"//cameraserver",
|
||||
":{}-snippets-headers".format(folder),
|
||||
],
|
||||
strip_include_prefix = "src/main/cpp/snippets/" + folder + "/include",
|
||||
tags = ["wpi-example"],
|
||||
@@ -83,7 +90,7 @@ def build_snippets():
|
||||
def build_templates():
|
||||
_package_type("templates")
|
||||
|
||||
for folder in TEMPLATES_FOLDERS:
|
||||
for folder in TEMPLATE_FOLDERS:
|
||||
cc_library(
|
||||
name = folder + "-template",
|
||||
srcs = native.glob(["src/main/cpp/templates/" + folder + "/**/*.cpp"]),
|
||||
@@ -96,7 +103,7 @@ def build_templates():
|
||||
)
|
||||
|
||||
def build_tests():
|
||||
for folder in TESTS_FOLDERS:
|
||||
for folder in EXAMPLE_TESTS_FOLDERS:
|
||||
example_src_folder = "src/main/cpp/examples/" + folder
|
||||
example_test_folder = "src/test/cpp/examples/" + folder
|
||||
cc_test(
|
||||
@@ -111,3 +118,18 @@ def build_tests():
|
||||
defines = ["RUNNING_WPILIB_TESTS=1"],
|
||||
tags = ["wpi-example", "no-tsan", "no-asan", "no-ubsan", "exclusive"],
|
||||
)
|
||||
for folder in SNIPPET_TESTS_FOLDERS:
|
||||
snippet_src_folder = "src/main/cpp/snippets/" + folder
|
||||
snippet_test_folder = "src/test/cpp/snippets/" + folder
|
||||
cc_test(
|
||||
name = folder + "-test",
|
||||
size = "small",
|
||||
srcs = native.glob([snippet_test_folder + "/**/*.cpp", snippet_src_folder + "/**/*.cpp"], allow_empty = True),
|
||||
deps = [
|
||||
"//commandsv2",
|
||||
":{}-snippets-headers".format(folder),
|
||||
"//thirdparty/googletest",
|
||||
],
|
||||
defines = ["RUNNING_WPILIB_TESTS=1"],
|
||||
tags = ["wpi-example", "no-tsan", "no-asan", "no-ubsan", "exclusive"],
|
||||
)
|
||||
|
||||
@@ -1,46 +1,28 @@
|
||||
EXAMPLE_FOLDERS = [
|
||||
"AddressableLED",
|
||||
"AprilTagsVision",
|
||||
"ArcadeDrive",
|
||||
"ArcadeDriveGamepad",
|
||||
"ArmSimulation",
|
||||
"CANPDP",
|
||||
"DifferentialDriveBot",
|
||||
"DifferentialDrivePoseEstimator",
|
||||
"DigitalCommunication",
|
||||
"DriveDistanceOffboard",
|
||||
"DutyCycleEncoder",
|
||||
"DutyCycleInput",
|
||||
"ElevatorExponentialProfile",
|
||||
"ElevatorExponentialSimulation",
|
||||
"ElevatorProfiledPID",
|
||||
"ElevatorSimulation",
|
||||
"ElevatorTrapezoidProfile",
|
||||
"Encoder",
|
||||
"EventLoop",
|
||||
"FlywheelBangBangController",
|
||||
"GettingStarted",
|
||||
"Gyro",
|
||||
"GyroMecanum",
|
||||
"HAL",
|
||||
"HatchbotInlined",
|
||||
"HatchbotTraditional",
|
||||
"HidRumble",
|
||||
"HttpCamera",
|
||||
"I2CCommunication",
|
||||
"IntermediateVision",
|
||||
"MecanumBot",
|
||||
"MecanumDrive",
|
||||
"MecanumDrivePoseEstimator",
|
||||
"Mechanism2d",
|
||||
"MotorControl",
|
||||
"PotentiometerPID",
|
||||
"QuickVision",
|
||||
"RapidReactCommandBot",
|
||||
"RomiReference",
|
||||
"SelectCommand",
|
||||
"SimpleDifferentialDriveSimulation",
|
||||
"Solenoid",
|
||||
"StateSpaceArm",
|
||||
"StateSpaceElevator",
|
||||
"StateSpaceFlywheel",
|
||||
@@ -48,7 +30,6 @@ EXAMPLE_FOLDERS = [
|
||||
"SwerveBot",
|
||||
"SwerveDrivePoseEstimator",
|
||||
"SysIdRoutine",
|
||||
"TankDrive",
|
||||
"TankDriveGamepad",
|
||||
"UnitTest",
|
||||
"XRPReference",
|
||||
@@ -66,25 +47,39 @@ COMMANDS_V2_FOLDERS = [
|
||||
"subsystem2",
|
||||
]
|
||||
|
||||
SNIPPETS_FOLDERS = [
|
||||
SNIPPET_FOLDERS = [
|
||||
"ADXLAccelerometers",
|
||||
"AccelerometerCollision",
|
||||
"AccelerometerFilter",
|
||||
"AddressableLED",
|
||||
"AnalogAccelerometer",
|
||||
"AnalogEncoder",
|
||||
"AnalogInput",
|
||||
"AnalogPotentiometer",
|
||||
"AprilTagsVision",
|
||||
"CANPDP",
|
||||
"DigitalCommunication",
|
||||
"DigitalInput",
|
||||
"DutyCycleEncoder",
|
||||
"DutyCycleInput",
|
||||
"Encoder",
|
||||
"EncoderDrive",
|
||||
"EncoderHoming",
|
||||
"EventLoop",
|
||||
"FlywheelBangBangController",
|
||||
"HttpCamera",
|
||||
"I2CCommunication",
|
||||
"IntermediateVision",
|
||||
"LimitSwitch",
|
||||
"MotorControl",
|
||||
"OnboardIMU",
|
||||
"ProfiledPIDFeedforward",
|
||||
"QuickVision",
|
||||
"SelectCommand",
|
||||
"Solenoid",
|
||||
]
|
||||
|
||||
TEMPLATES_FOLDERS = [
|
||||
TEMPLATE_FOLDERS = [
|
||||
"commandv2",
|
||||
"commandv2skeleton",
|
||||
"opmode",
|
||||
@@ -95,11 +90,13 @@ TEMPLATES_FOLDERS = [
|
||||
"timesliceskeleton",
|
||||
]
|
||||
|
||||
TESTS_FOLDERS = [
|
||||
EXAMPLE_TESTS_FOLDERS = [
|
||||
"ArmSimulation",
|
||||
"DigitalCommunication",
|
||||
"ElevatorSimulation",
|
||||
"I2CCommunication",
|
||||
"PotentiometerPID",
|
||||
"UnitTest",
|
||||
]
|
||||
|
||||
SNIPPET_TESTS_FOLDERS = [
|
||||
"DigitalCommunication",
|
||||
"I2CCommunication",
|
||||
]
|
||||
|
||||
@@ -34,7 +34,8 @@ def main():
|
||||
"wpilibcExamples/src/main/cpp/templates/templates.json"
|
||||
)
|
||||
snippets = load_foldernames("wpilibcExamples/src/main/cpp/snippets/snippets.json")
|
||||
tests = load_tests("wpilibcExamples/src/main/cpp/examples/examples.json")
|
||||
example_tests = load_tests("wpilibcExamples/src/main/cpp/examples/examples.json")
|
||||
snippet_tests = load_tests("wpilibcExamples/src/main/cpp/snippets/snippets.json")
|
||||
|
||||
output_file = "wpilibcExamples/example_projects.bzl"
|
||||
if len(sys.argv) == 2:
|
||||
@@ -45,13 +46,20 @@ def main():
|
||||
f.write(
|
||||
'COMMANDS_V2_FOLDERS = [\n "' + '",\n "'.join(commands) + '",\n]\n\n'
|
||||
)
|
||||
f.write('SNIPPET_FOLDERS = [\n "' + '",\n "'.join(snippets) + '",\n]\n\n')
|
||||
f.write(
|
||||
'SNIPPETS_FOLDERS = [\n "' + '",\n "'.join(snippets) + '",\n]\n\n'
|
||||
'TEMPLATE_FOLDERS = [\n "' + '",\n "'.join(templates) + '",\n]\n\n'
|
||||
)
|
||||
f.write(
|
||||
'TEMPLATES_FOLDERS = [\n "' + '",\n "'.join(templates) + '",\n]\n\n'
|
||||
'EXAMPLE_TESTS_FOLDERS = [\n "'
|
||||
+ '",\n "'.join(example_tests)
|
||||
+ '",\n]\n\n'
|
||||
)
|
||||
f.write(
|
||||
'SNIPPET_TESTS_FOLDERS = [\n "'
|
||||
+ '",\n "'.join(snippet_tests)
|
||||
+ '",\n]\n'
|
||||
)
|
||||
f.write('TESTS_FOLDERS = [\n "' + '",\n "'.join(tests) + '",\n]\n')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "wpi/drive/DifferentialDrive.hpp"
|
||||
#include "wpi/driverstation/Joystick.hpp"
|
||||
#include "wpi/framework/TimedRobot.hpp"
|
||||
#include "wpi/hardware/motor/PWMSparkMax.hpp"
|
||||
|
||||
/**
|
||||
* This is a demo program showing the use of the DifferentialDrive class.
|
||||
* Runs the motors with arcade steering.
|
||||
*/
|
||||
class Robot : public wpi::TimedRobot {
|
||||
wpi::PWMSparkMax m_leftMotor{0};
|
||||
wpi::PWMSparkMax m_rightMotor{1};
|
||||
wpi::DifferentialDrive m_robotDrive{
|
||||
[&](double output) { m_leftMotor.SetDutyCycle(output); },
|
||||
[&](double output) { m_rightMotor.SetDutyCycle(output); }};
|
||||
wpi::Joystick m_stick{0};
|
||||
|
||||
public:
|
||||
Robot() {
|
||||
wpi::util::SendableRegistry::AddChild(&m_robotDrive, &m_leftMotor);
|
||||
wpi::util::SendableRegistry::AddChild(&m_robotDrive, &m_rightMotor);
|
||||
|
||||
// We need to invert one side of the drivetrain so that positive voltages
|
||||
// result in both sides moving forward. Depending on how your robot's
|
||||
// gearbox is constructed, you might have to invert the left side instead.
|
||||
m_rightMotor.SetInverted(true);
|
||||
}
|
||||
|
||||
void TeleopPeriodic() override {
|
||||
// Drive with arcade style
|
||||
m_robotDrive.ArcadeDrive(-m_stick.GetY(), -m_stick.GetX());
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef RUNNING_WPILIB_TESTS
|
||||
int main() {
|
||||
return wpi::StartRobot<Robot>();
|
||||
}
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "wpi/drive/MecanumDrive.hpp"
|
||||
#include "wpi/driverstation/Joystick.hpp"
|
||||
#include "wpi/framework/TimedRobot.hpp"
|
||||
#include "wpi/hardware/imu/OnboardIMU.hpp"
|
||||
#include "wpi/hardware/motor/PWMSparkMax.hpp"
|
||||
|
||||
/**
|
||||
* This is a sample program that uses mecanum drive with a gyro sensor to
|
||||
* maintain rotation vectors in relation to the starting orientation of the
|
||||
* robot (field-oriented controls).
|
||||
*/
|
||||
class Robot : public wpi::TimedRobot {
|
||||
public:
|
||||
Robot() {
|
||||
wpi::util::SendableRegistry::AddChild(&m_robotDrive, &m_frontLeft);
|
||||
wpi::util::SendableRegistry::AddChild(&m_robotDrive, &m_rearLeft);
|
||||
wpi::util::SendableRegistry::AddChild(&m_robotDrive, &m_frontRight);
|
||||
wpi::util::SendableRegistry::AddChild(&m_robotDrive, &m_rearRight);
|
||||
|
||||
// Invert the right side motors. You may need to change or remove this to
|
||||
// match your robot.
|
||||
m_frontRight.SetInverted(true);
|
||||
m_rearRight.SetInverted(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mecanum drive is used with the gyro angle as an input.
|
||||
*/
|
||||
void TeleopPeriodic() override {
|
||||
m_robotDrive.DriveCartesian(-m_joystick.GetY(), -m_joystick.GetX(),
|
||||
-m_joystick.GetZ(), m_imu.GetRotation2d());
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr int kFrontLeftMotorPort = 0;
|
||||
static constexpr int kRearLeftMotorPort = 1;
|
||||
static constexpr int kFrontRightMotorPort = 2;
|
||||
static constexpr int kRearRightMotorPort = 3;
|
||||
static constexpr wpi::OnboardIMU::MountOrientation kIMUMountOrientation =
|
||||
wpi::OnboardIMU::kFlat;
|
||||
static constexpr int kJoystickPort = 0;
|
||||
|
||||
wpi::PWMSparkMax m_frontLeft{kFrontLeftMotorPort};
|
||||
wpi::PWMSparkMax m_rearLeft{kRearLeftMotorPort};
|
||||
wpi::PWMSparkMax m_frontRight{kFrontRightMotorPort};
|
||||
wpi::PWMSparkMax m_rearRight{kRearRightMotorPort};
|
||||
wpi::MecanumDrive m_robotDrive{
|
||||
[&](double output) { m_frontLeft.SetDutyCycle(output); },
|
||||
[&](double output) { m_rearLeft.SetDutyCycle(output); },
|
||||
[&](double output) { m_frontRight.SetDutyCycle(output); },
|
||||
[&](double output) { m_rearRight.SetDutyCycle(output); }};
|
||||
|
||||
wpi::OnboardIMU m_imu{kIMUMountOrientation};
|
||||
wpi::Joystick m_joystick{kJoystickPort};
|
||||
};
|
||||
|
||||
#ifndef RUNNING_WPILIB_TESTS
|
||||
int main() {
|
||||
return wpi::StartRobot<Robot>();
|
||||
}
|
||||
#endif
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "wpi/driverstation/Gamepad.hpp"
|
||||
#include "wpi/framework/TimedRobot.hpp"
|
||||
|
||||
/**
|
||||
* This is a demo program showing the use of GenericHID's rumble feature.
|
||||
*/
|
||||
class Robot : public wpi::TimedRobot {
|
||||
public:
|
||||
void AutonomousInit() override {
|
||||
// Turn on rumble at the start of auto
|
||||
m_hid.SetRumble(wpi::GenericHID::RumbleType::kLeftRumble, 1.0);
|
||||
m_hid.SetRumble(wpi::GenericHID::RumbleType::kRightRumble, 1.0);
|
||||
}
|
||||
|
||||
void DisabledInit() override {
|
||||
// Stop the rumble when entering disabled
|
||||
m_hid.SetRumble(wpi::GenericHID::RumbleType::kLeftRumble, 0.0);
|
||||
m_hid.SetRumble(wpi::GenericHID::RumbleType::kRightRumble, 0.0);
|
||||
}
|
||||
|
||||
private:
|
||||
wpi::GenericHID m_hid{0};
|
||||
};
|
||||
|
||||
#ifndef RUNNING_WPILIB_TESTS
|
||||
int main() {
|
||||
return wpi::StartRobot<Robot>();
|
||||
}
|
||||
#endif
|
||||
@@ -5,11 +5,13 @@
|
||||
#include "wpi/drive/MecanumDrive.hpp"
|
||||
#include "wpi/driverstation/Joystick.hpp"
|
||||
#include "wpi/framework/TimedRobot.hpp"
|
||||
#include "wpi/hardware/imu/OnboardIMU.hpp"
|
||||
#include "wpi/hardware/motor/PWMSparkMax.hpp"
|
||||
|
||||
/**
|
||||
* This is a demo program showing how to use Mecanum control with the
|
||||
* MecanumDrive class.
|
||||
* This is a sample program that uses mecanum drive with a gyro sensor to
|
||||
* maintain rotation vectors in relation to the starting orientation of the
|
||||
* robot (field-oriented controls).
|
||||
*/
|
||||
class Robot : public wpi::TimedRobot {
|
||||
public:
|
||||
@@ -25,33 +27,38 @@ class Robot : public wpi::TimedRobot {
|
||||
m_rearRight.SetInverted(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mecanum drive is used with the gyro angle as an input.
|
||||
*/
|
||||
void TeleopPeriodic() override {
|
||||
/* Use the joystick Y axis for forward movement, X axis for lateral
|
||||
* movement, and Z axis for rotation.
|
||||
*/
|
||||
m_robotDrive.DriveCartesian(-m_stick.GetY(), -m_stick.GetX(),
|
||||
-m_stick.GetZ());
|
||||
m_robotDrive.DriveCartesian(-m_joystick.GetY(), -m_joystick.GetX(),
|
||||
-m_joystick.GetZ(), m_imu.GetRotation2d());
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr int kFrontLeftChannel = 0;
|
||||
static constexpr int kRearLeftChannel = 1;
|
||||
static constexpr int kFrontRightChannel = 2;
|
||||
static constexpr int kRearRightChannel = 3;
|
||||
static constexpr int kFrontLeftMotorPort = 0;
|
||||
static constexpr int kRearLeftMotorPort = 1;
|
||||
static constexpr int kFrontRightMotorPort = 2;
|
||||
static constexpr int kRearRightMotorPort = 3;
|
||||
static constexpr wpi::OnboardIMU::MountOrientation kIMUMountOrientation =
|
||||
wpi::OnboardIMU::kFlat;
|
||||
static constexpr int kJoystickPort = 0;
|
||||
|
||||
static constexpr int kJoystickChannel = 0;
|
||||
|
||||
wpi::PWMSparkMax m_frontLeft{kFrontLeftChannel};
|
||||
wpi::PWMSparkMax m_rearLeft{kRearLeftChannel};
|
||||
wpi::PWMSparkMax m_frontRight{kFrontRightChannel};
|
||||
wpi::PWMSparkMax m_rearRight{kRearRightChannel};
|
||||
wpi::PWMSparkMax m_frontLeft{kFrontLeftMotorPort};
|
||||
wpi::PWMSparkMax m_rearLeft{kRearLeftMotorPort};
|
||||
wpi::PWMSparkMax m_frontRight{kFrontRightMotorPort};
|
||||
wpi::PWMSparkMax m_rearRight{kRearRightMotorPort};
|
||||
wpi::MecanumDrive m_robotDrive{
|
||||
[&](double output) { m_frontLeft.SetDutyCycle(output); },
|
||||
[&](double output) { m_rearLeft.SetDutyCycle(output); },
|
||||
[&](double output) { m_frontRight.SetDutyCycle(output); },
|
||||
[&](double output) { m_rearRight.SetDutyCycle(output); }};
|
||||
|
||||
wpi::Joystick m_stick{kJoystickChannel};
|
||||
wpi::OnboardIMU m_imu{kIMUMountOrientation};
|
||||
wpi::Joystick m_joystick{kJoystickPort};
|
||||
};
|
||||
|
||||
#ifndef RUNNING_WPILIB_TESTS
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "Robot.hpp"
|
||||
|
||||
void Robot::TeleopInit() {
|
||||
// Move to the bottom setpoint when teleop starts
|
||||
m_index = 0;
|
||||
m_pidController.SetSetpoint(kSetpoints[m_index].value());
|
||||
}
|
||||
|
||||
void Robot::TeleopPeriodic() {
|
||||
// Read from the sensor
|
||||
wpi::units::meter_t position = wpi::units::meter_t{m_potentiometer.Get()};
|
||||
|
||||
// Run the PID Controller
|
||||
double pidOut = m_pidController.Calculate(position.value());
|
||||
|
||||
// Apply PID output
|
||||
m_elevatorMotor.SetDutyCycle(pidOut);
|
||||
|
||||
// when the button is pressed once, the selected elevator setpoint is
|
||||
// incremented
|
||||
if (m_joystick.GetTriggerPressed()) {
|
||||
// index of the elevator setpoint wraps around.
|
||||
m_index = (m_index + 1) % kSetpoints.size();
|
||||
m_pidController.SetSetpoint(kSetpoints[m_index].value());
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef RUNNING_WPILIB_TESTS
|
||||
int main() {
|
||||
return wpi::StartRobot<Robot>();
|
||||
}
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "wpi/driverstation/Joystick.hpp"
|
||||
#include "wpi/framework/TimedRobot.hpp"
|
||||
#include "wpi/hardware/motor/PWMSparkMax.hpp"
|
||||
#include "wpi/hardware/rotation/AnalogPotentiometer.hpp"
|
||||
#include "wpi/math/controller/PIDController.hpp"
|
||||
#include "wpi/units/length.hpp"
|
||||
|
||||
/**
|
||||
* This is a sample program to demonstrate how to use a soft potentiometer and a
|
||||
* PID controller to reach and maintain position setpoints on an elevator
|
||||
* mechanism.
|
||||
*/
|
||||
class Robot : public wpi::TimedRobot {
|
||||
public:
|
||||
void TeleopInit() override;
|
||||
void TeleopPeriodic() override;
|
||||
|
||||
static constexpr int kPotChannel = 1;
|
||||
static constexpr int kMotorChannel = 7;
|
||||
static constexpr int kJoystickChannel = 3;
|
||||
|
||||
// The elevator can move 1.5 meters from top to bottom
|
||||
static constexpr wpi::units::meter_t kFullHeight = 1.5_m;
|
||||
|
||||
// Bottom, middle, and top elevator setpoints
|
||||
static constexpr std::array<wpi::units::meter_t, 3> kSetpoints = {
|
||||
{0.2_m, 0.8_m, 1.4_m}};
|
||||
|
||||
private:
|
||||
// proportional velocity constant
|
||||
// negative because applying positive voltage will bring us closer to the
|
||||
// target
|
||||
static constexpr double kP = 0.7;
|
||||
// integral velocity constant
|
||||
static constexpr double kI = 0.35;
|
||||
// derivative velocity constant
|
||||
static constexpr double kD = 0.25;
|
||||
|
||||
// Scaling is handled internally
|
||||
wpi::AnalogPotentiometer m_potentiometer{kPotChannel, kFullHeight.value()};
|
||||
|
||||
wpi::PWMSparkMax m_elevatorMotor{kMotorChannel};
|
||||
wpi::math::PIDController m_pidController{kP, kI, kD};
|
||||
wpi::Joystick m_joystick{kJoystickChannel};
|
||||
|
||||
size_t m_index;
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "wpi/drive/DifferentialDrive.hpp"
|
||||
#include "wpi/driverstation/Joystick.hpp"
|
||||
#include "wpi/framework/TimedRobot.hpp"
|
||||
#include "wpi/hardware/motor/PWMSparkMax.hpp"
|
||||
|
||||
/**
|
||||
* This is a demo program showing the use of the DifferentialDrive class.
|
||||
* Runs the motors with tank steering.
|
||||
*/
|
||||
class Robot : public wpi::TimedRobot {
|
||||
wpi::PWMSparkMax m_leftMotor{0};
|
||||
wpi::PWMSparkMax m_rightMotor{1};
|
||||
wpi::DifferentialDrive m_robotDrive{
|
||||
[&](double output) { m_leftMotor.SetDutyCycle(output); },
|
||||
[&](double output) { m_rightMotor.SetDutyCycle(output); }};
|
||||
wpi::Joystick m_leftStick{0};
|
||||
wpi::Joystick m_rightStick{1};
|
||||
|
||||
public:
|
||||
Robot() {
|
||||
wpi::util::SendableRegistry::AddChild(&m_robotDrive, &m_leftMotor);
|
||||
wpi::util::SendableRegistry::AddChild(&m_robotDrive, &m_rightMotor);
|
||||
|
||||
// We need to invert one side of the drivetrain so that positive voltages
|
||||
// result in both sides moving forward. Depending on how your robot's
|
||||
// gearbox is constructed, you might have to invert the left side instead.
|
||||
m_rightMotor.SetInverted(true);
|
||||
}
|
||||
|
||||
void TeleopPeriodic() override {
|
||||
// Drive with tank style
|
||||
m_robotDrive.TankDrive(-m_leftStick.GetY(), -m_rightStick.GetY());
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef RUNNING_WPILIB_TESTS
|
||||
int main() {
|
||||
return wpi::StartRobot<Robot>();
|
||||
}
|
||||
#endif
|
||||
@@ -1,29 +1,4 @@
|
||||
[
|
||||
{
|
||||
"name": "Motor Control",
|
||||
"description": "Control a single motor with a joystick, displaying the movement of the motor using an encoder.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Encoder",
|
||||
"SmartDashboard",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "MotorControl",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "PDP CAN Monitoring",
|
||||
"description": "Monitor Power Distribution data such as voltage, current, temperature, etc.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"PDP",
|
||||
"SmartDashboard"
|
||||
],
|
||||
"foldername": "CANPDP",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Mechanism2d",
|
||||
"foldername": "Mechanism2d",
|
||||
@@ -40,18 +15,6 @@
|
||||
],
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Solenoids",
|
||||
"description": "Control a single and double solenoid from joystick buttons.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Joystick",
|
||||
"Pneumatics"
|
||||
],
|
||||
"foldername": "Solenoid",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Encoder",
|
||||
"description": "View values from a quadrature encoder.",
|
||||
@@ -64,54 +27,6 @@
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "EventLoop",
|
||||
"description": "Manage a ball system using EventLoop and BooleanEvent.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Flywheel",
|
||||
"EventLoop"
|
||||
],
|
||||
"foldername": "EventLoop",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Arcade Drive",
|
||||
"description": "Control a differential drivetrain with single-joystick arcade drive in teleop.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Differential Drive",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "ArcadeDrive",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Tank Drive",
|
||||
"description": "Control a differential drive with twin-joystick tank drive in teleop.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Differential Drive",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "TankDrive",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Mecanum Drive",
|
||||
"description": "Control a mecanum drivetrain with a joystick in teleop.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Mecanum Drive",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "MecanumDrive",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Gyro",
|
||||
"description": "Drive a differential drive straight with a gyro sensor.",
|
||||
@@ -120,7 +35,6 @@
|
||||
"Differential Drive",
|
||||
"PID",
|
||||
"Gyro",
|
||||
"Analog",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "Gyro",
|
||||
@@ -128,45 +42,18 @@
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Gyro Mecanum",
|
||||
"name": "Mecanum Drive",
|
||||
"description": "Drive a mecanum drivetrain using field-oriented controls with a joystick.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Mecanum Drive",
|
||||
"Gyro",
|
||||
"Analog",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "GyroMecanum",
|
||||
"foldername": "MecanumDrive",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "HID Rumble",
|
||||
"description": "Make human interface devices (HID) rumble.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Gamepad"
|
||||
],
|
||||
"foldername": "HidRumble",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "PotentiometerPID",
|
||||
"description": "Maintain elevator position setpoints with a potentiometer and PID control.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Analog",
|
||||
"Elevator",
|
||||
"PID",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "PotentiometerPID",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2,
|
||||
"hasunittests": true
|
||||
},
|
||||
{
|
||||
"name": "Elevator with exponential profiled PID",
|
||||
"description": "Reach elevator position setpoints with exponential profiles and smart motor controller PID.",
|
||||
@@ -218,71 +105,6 @@
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Simple Vision",
|
||||
"description": "Use the CameraServer class to stream from a USB Webcam without processing the images.",
|
||||
"tags": [
|
||||
"Vision"
|
||||
],
|
||||
"foldername": "QuickVision",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Intermediate Vision",
|
||||
"description": "Acquire images from an attached USB camera and add some annotation to the image (as you might do for showing operators the result of some image recognition) and send it to the dashboard for display.",
|
||||
"tags": [
|
||||
"Vision"
|
||||
],
|
||||
"foldername": "IntermediateVision",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "AprilTags Vision",
|
||||
"description": "On-roboRIO detection of AprilTags using an attached USB camera.",
|
||||
"tags": [
|
||||
"Vision",
|
||||
"AprilTags"
|
||||
],
|
||||
"foldername": "AprilTagsVision",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "I2C Communication",
|
||||
"description": "Communicate with external devices (such as an Arduino) using the roboRIO's I2C port.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"I2C"
|
||||
],
|
||||
"foldername": "I2CCommunication",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2,
|
||||
"hasunittests": true
|
||||
},
|
||||
{
|
||||
"name": "Digital Communication Sample",
|
||||
"description": "Communicates with external devices (such as an Arduino) using the roboRIO's DIO.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Digital Output"
|
||||
],
|
||||
"foldername": "DigitalCommunication",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2,
|
||||
"hasunittests": true
|
||||
},
|
||||
{
|
||||
"name": "HTTP Camera",
|
||||
"description": "Acquire images from an HTTP network camera and adds some annotation to the image (as you might do for showing operators the result of some image recognition), and sends it to the dashboard for display.",
|
||||
"tags": [
|
||||
"Vision"
|
||||
],
|
||||
"foldername": "HttpCamera",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "HAL",
|
||||
"description": "Use the low-level HAL C functions. This example is for advanced users.",
|
||||
@@ -349,16 +171,6 @@
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Select Command Example",
|
||||
"description": "Use SelectCommand to select an autonomous routine.",
|
||||
"tags": [
|
||||
"Commandv2"
|
||||
],
|
||||
"foldername": "SelectCommand",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "SwerveBot",
|
||||
"description": "Use kinematics and odometry with a swerve drive.",
|
||||
@@ -438,30 +250,6 @@
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Duty Cycle Input",
|
||||
"description": "View duty-cycle input.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Duty Cycle",
|
||||
"SmartDashboard"
|
||||
],
|
||||
"foldername": "DutyCycleInput",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Addressable LED",
|
||||
"description": "Display a rainbow pattern on an addressable LED strip.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Basic Robot",
|
||||
"AddressableLEDs"
|
||||
],
|
||||
"foldername": "AddressableLED",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "DriveDistanceOffboard",
|
||||
"description": "Drive a differential drivetrain a set distance using TrapezoidProfile and smart motor controller PID.",
|
||||
@@ -707,18 +495,6 @@
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Flywheel BangBangController",
|
||||
"description": "A sample program to demonstrate the use of a BangBangController with a flywheel to control RPM",
|
||||
"tags": [
|
||||
"Flywheel",
|
||||
"Simulation",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "FlywheelBangBangController",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "SysIdRoutine",
|
||||
"description": "A sample Commandv2 robot demonstrating use of the SysIdRoutine command factory",
|
||||
|
||||
@@ -156,5 +156,152 @@
|
||||
],
|
||||
"foldername": "ProfiledPIDFeedforward",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "Addressable LED",
|
||||
"description": "Display a rainbow pattern on an addressable LED strip.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Basic Robot",
|
||||
"AddressableLEDs"
|
||||
],
|
||||
"foldername": "AddressableLED",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "AprilTags Vision",
|
||||
"description": "On-roboRIO detection of AprilTags using an attached USB camera.",
|
||||
"tags": [
|
||||
"Vision",
|
||||
"AprilTags"
|
||||
],
|
||||
"foldername": "AprilTagsVision",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "PDP CAN Monitoring",
|
||||
"description": "Monitor Power Distribution data such as voltage, current, temperature, etc.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"PDP",
|
||||
"SmartDashboard"
|
||||
],
|
||||
"foldername": "CANPDP",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "Digital Communication Sample",
|
||||
"description": "Communicates with external devices (such as an Arduino) using the roboRIO's DIO.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Digital Output"
|
||||
],
|
||||
"foldername": "DigitalCommunication",
|
||||
"gradlebase": "cpp",
|
||||
"hasunittests": true
|
||||
},
|
||||
{
|
||||
"name": "Duty Cycle Input",
|
||||
"description": "View duty-cycle input.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Duty Cycle",
|
||||
"SmartDashboard"
|
||||
],
|
||||
"foldername": "DutyCycleInput",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "EventLoop",
|
||||
"description": "Manage a ball system using EventLoop and BooleanEvent.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Flywheel",
|
||||
"EventLoop"
|
||||
],
|
||||
"foldername": "EventLoop",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "Flywheel BangBangController",
|
||||
"description": "A sample program to demonstrate the use of a BangBangController with a flywheel to control RPM",
|
||||
"tags": [
|
||||
"Flywheel",
|
||||
"Simulation",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "FlywheelBangBangController",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "HTTP Camera",
|
||||
"description": "Acquire images from an HTTP network camera and adds some annotation to the image (as you might do for showing operators the result of some image recognition), and sends it to the dashboard for display.",
|
||||
"tags": [
|
||||
"Vision"
|
||||
],
|
||||
"foldername": "HttpCamera",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "I2C Communication",
|
||||
"description": "Communicate with external devices (such as an Arduino) using the roboRIO's I2C port.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"I2C"
|
||||
],
|
||||
"foldername": "I2CCommunication",
|
||||
"gradlebase": "cpp",
|
||||
"hasunittests": true
|
||||
},
|
||||
{
|
||||
"name": "Intermediate Vision",
|
||||
"description": "Acquire images from an attached USB camera and add some annotation to the image (as you might do for showing operators the result of some image recognition) and send it to the dashboard for display.",
|
||||
"tags": [
|
||||
"Vision"
|
||||
],
|
||||
"foldername": "IntermediateVision",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "Motor Control",
|
||||
"description": "Control a single motor with a joystick, displaying the movement of the motor using an encoder.",
|
||||
"tags": [
|
||||
"Basic Robot",
|
||||
"Encoder",
|
||||
"SmartDashboard",
|
||||
"Joystick"
|
||||
],
|
||||
"foldername": "MotorControl",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "Select Command Example",
|
||||
"description": "Use SelectCommand to select an autonomous routine.",
|
||||
"tags": [
|
||||
"Commandv2"
|
||||
],
|
||||
"foldername": "SelectCommand",
|
||||
"gradlebase": "cpp",
|
||||
"commandversion": 2
|
||||
},
|
||||
{
|
||||
"name": "Simple Vision",
|
||||
"description": "Use the CameraServer class to stream from a USB Webcam without processing the images.",
|
||||
"tags": [
|
||||
"Vision"
|
||||
],
|
||||
"foldername": "QuickVision",
|
||||
"gradlebase": "cpp"
|
||||
},
|
||||
{
|
||||
"name": "Solenoids",
|
||||
"description": "Control a single and double solenoid from joystick buttons.",
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Joystick",
|
||||
"Pneumatics"
|
||||
],
|
||||
"foldername": "Solenoid",
|
||||
"gradlebase": "cpp"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Robot.hpp"
|
||||
#include "wpi/hal/DriverStationTypes.h"
|
||||
#include "wpi/hal/simulation/MockHooks.h"
|
||||
#include "wpi/math/system/DCMotor.hpp"
|
||||
#include "wpi/simulation/AnalogInputSim.hpp"
|
||||
#include "wpi/simulation/DriverStationSim.hpp"
|
||||
#include "wpi/simulation/ElevatorSim.hpp"
|
||||
#include "wpi/simulation/JoystickSim.hpp"
|
||||
#include "wpi/simulation/PWMMotorControllerSim.hpp"
|
||||
#include "wpi/simulation/SimHooks.hpp"
|
||||
#include "wpi/system/RobotController.hpp"
|
||||
#include "wpi/units/length.hpp"
|
||||
#include "wpi/units/mass.hpp"
|
||||
#include "wpi/units/time.hpp"
|
||||
|
||||
class PotentiometerPIDTest : public testing::Test {
|
||||
wpi::math::DCMotor m_elevatorGearbox = wpi::math::DCMotor::Vex775Pro(4);
|
||||
static constexpr double kElevatorGearing = 10.0;
|
||||
static constexpr wpi::units::meter_t kElevatorDrumRadius = 2.0_in;
|
||||
static constexpr wpi::units::kilogram_t kCarriageMass = 4.0_kg;
|
||||
|
||||
Robot m_robot;
|
||||
std::optional<std::thread> m_thread;
|
||||
|
||||
protected:
|
||||
wpi::sim::ElevatorSim m_elevatorSim{m_elevatorGearbox,
|
||||
kElevatorGearing,
|
||||
kCarriageMass,
|
||||
kElevatorDrumRadius,
|
||||
0.0_m,
|
||||
Robot::kFullHeight,
|
||||
true,
|
||||
0.0_m};
|
||||
wpi::sim::PWMMotorControllerSim m_motorSim{Robot::kMotorChannel};
|
||||
wpi::sim::AnalogInputSim m_analogSim{Robot::kPotChannel};
|
||||
wpi::sim::JoystickSim m_joystickSim{Robot::kJoystickChannel};
|
||||
int32_t m_callback;
|
||||
int32_t m_port;
|
||||
|
||||
public:
|
||||
void SimPeriodicBefore() {
|
||||
m_elevatorSim.SetInputVoltage(m_motorSim.GetDutyCycle() *
|
||||
wpi::RobotController::GetBatteryVoltage());
|
||||
m_elevatorSim.Update(20_ms);
|
||||
|
||||
/*
|
||||
meters = (v / 3.3v) * range
|
||||
meters / range = v / 3.3v
|
||||
3.3v * (meters / range) = v
|
||||
*/
|
||||
m_analogSim.SetVoltage(
|
||||
(wpi::RobotController::GetVoltage3V3() *
|
||||
(m_elevatorSim.GetPosition().value() / Robot::kFullHeight))
|
||||
.value());
|
||||
}
|
||||
|
||||
static void CallSimPeriodicBefore(void* param) {
|
||||
static_cast<PotentiometerPIDTest*>(param)->SimPeriodicBefore();
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
wpi::sim::PauseTiming();
|
||||
wpi::sim::SetProgramStarted(false);
|
||||
wpi::sim::DriverStationSim::ResetData();
|
||||
|
||||
m_joystickSim.SetButtonsMaximumIndex(12);
|
||||
|
||||
m_callback =
|
||||
HALSIM_RegisterSimPeriodicBeforeCallback(CallSimPeriodicBefore, this);
|
||||
|
||||
m_thread = std::thread([&] { m_robot.StartCompetition(); });
|
||||
wpi::sim::WaitForProgramStart();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
m_robot.EndCompetition();
|
||||
m_thread->join();
|
||||
|
||||
HALSIM_CancelSimPeriodicBeforeCallback(m_callback);
|
||||
m_analogSim.ResetData();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(PotentiometerPIDTest, Teleop) {
|
||||
// teleop init
|
||||
{
|
||||
wpi::sim::DriverStationSim::SetRobotMode(HAL_ROBOTMODE_TELEOPERATED);
|
||||
wpi::sim::DriverStationSim::SetEnabled(true);
|
||||
wpi::sim::DriverStationSim::NotifyNewData();
|
||||
|
||||
EXPECT_TRUE(m_analogSim.GetInitialized());
|
||||
}
|
||||
|
||||
// first setpoint
|
||||
{
|
||||
// advance 50 timesteps
|
||||
wpi::sim::StepTiming(1_s);
|
||||
|
||||
EXPECT_NEAR(Robot::kSetpoints[0].value(),
|
||||
m_elevatorSim.GetPosition().value(), 0.1);
|
||||
}
|
||||
|
||||
// second setpoint
|
||||
{
|
||||
// press button to advance setpoint
|
||||
m_joystickSim.SetTrigger(true);
|
||||
m_joystickSim.NotifyNewData();
|
||||
|
||||
// advance 50 timesteps
|
||||
wpi::sim::StepTiming(1_s);
|
||||
|
||||
EXPECT_NEAR(Robot::kSetpoints[1].value(),
|
||||
m_elevatorSim.GetPosition().value(), 0.1);
|
||||
}
|
||||
|
||||
// we need to unpress the button
|
||||
{
|
||||
m_joystickSim.SetTrigger(false);
|
||||
m_joystickSim.NotifyNewData();
|
||||
|
||||
// advance 10 timesteps
|
||||
wpi::sim::StepTiming(0.2_s);
|
||||
}
|
||||
|
||||
// third setpoint
|
||||
{
|
||||
// press button to advance setpoint
|
||||
m_joystickSim.SetTrigger(true);
|
||||
m_joystickSim.NotifyNewData();
|
||||
|
||||
// advance 50 timesteps
|
||||
wpi::sim::StepTiming(1_s);
|
||||
|
||||
EXPECT_NEAR(Robot::kSetpoints[2].value(),
|
||||
m_elevatorSim.GetPosition().value(), 0.1);
|
||||
}
|
||||
|
||||
// we need to unpress the button
|
||||
{
|
||||
m_joystickSim.SetTrigger(false);
|
||||
m_joystickSim.NotifyNewData();
|
||||
|
||||
// advance 10 timesteps
|
||||
wpi::sim::StepTiming(0.2_s);
|
||||
}
|
||||
|
||||
// rollover: first setpoint
|
||||
{
|
||||
// press button to advance setpoint
|
||||
m_joystickSim.SetTrigger(true);
|
||||
m_joystickSim.NotifyNewData();
|
||||
|
||||
// advance 60 timesteps
|
||||
wpi::sim::StepTiming(1.2_s);
|
||||
EXPECT_NEAR(Robot::kSetpoints[0].value(),
|
||||
m_elevatorSim.GetPosition().value(), 0.1);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "wpi/hal/HAL.h"
|
||||
|
||||
/**
|
||||
* Runs all unit tests.
|
||||
*/
|
||||
int main(int argc, char** argv) {
|
||||
HAL_Initialize(500, 0);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user