2021-05-21 22:34:16 -07:00
|
|
|
// 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.
|
|
|
|
|
|
2023-08-28 15:13:34 -07:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
2025-11-07 19:56:21 -05:00
|
|
|
#include "motorcontrol/MockPWMMotorController.hpp"
|
2025-11-07 19:57:55 -05:00
|
|
|
#include "wpi/drive/MecanumDrive.hpp"
|
2021-05-21 22:34:16 -07:00
|
|
|
|
2022-02-17 18:03:59 -08:00
|
|
|
TEST(MecanumDriveTest, CartesianIK) {
|
|
|
|
|
// Forward
|
2025-11-07 20:00:05 -05:00
|
|
|
auto speeds = wpi::MecanumDrive::DriveCartesianIK(1.0, 0.0, 0.0);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearRight);
|
|
|
|
|
|
|
|
|
|
// Left
|
2025-11-07 20:00:05 -05:00
|
|
|
speeds = wpi::MecanumDrive::DriveCartesianIK(0.0, -1.0, 0.0);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearRight);
|
|
|
|
|
|
|
|
|
|
// Right
|
2025-11-07 20:00:05 -05:00
|
|
|
speeds = wpi::MecanumDrive::DriveCartesianIK(0.0, 1.0, 0.0);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearRight);
|
|
|
|
|
|
|
|
|
|
// Rotate CCW
|
2025-11-07 20:00:05 -05:00
|
|
|
speeds = wpi::MecanumDrive::DriveCartesianIK(0.0, 0.0, -1.0);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearRight);
|
|
|
|
|
|
|
|
|
|
// Rotate CW
|
2025-11-07 20:00:05 -05:00
|
|
|
speeds = wpi::MecanumDrive::DriveCartesianIK(0.0, 0.0, 1.0);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearRight);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(MecanumDriveTest, CartesianIKGyro90CW) {
|
|
|
|
|
// Forward in global frame; left in robot frame
|
2025-11-07 20:00:05 -05:00
|
|
|
auto speeds = wpi::MecanumDrive::DriveCartesianIK(1.0, 0.0, 0.0, 90_deg);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearRight);
|
|
|
|
|
|
|
|
|
|
// Left in global frame; backward in robot frame
|
2025-11-07 20:00:05 -05:00
|
|
|
speeds = wpi::MecanumDrive::DriveCartesianIK(0.0, -1.0, 0.0, 90_deg);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearRight);
|
|
|
|
|
|
|
|
|
|
// Right in global frame; forward in robot frame
|
2025-11-07 20:00:05 -05:00
|
|
|
speeds = wpi::MecanumDrive::DriveCartesianIK(0.0, 1.0, 0.0, 90_deg);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearRight);
|
|
|
|
|
|
|
|
|
|
// Rotate CCW
|
2025-11-07 20:00:05 -05:00
|
|
|
speeds = wpi::MecanumDrive::DriveCartesianIK(0.0, 0.0, -1.0, 90_deg);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearRight);
|
|
|
|
|
|
|
|
|
|
// Rotate CW
|
2025-11-07 20:00:05 -05:00
|
|
|
speeds = wpi::MecanumDrive::DriveCartesianIK(0.0, 0.0, 1.0, 90_deg);
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.frontLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.frontRight);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, speeds.rearLeft);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, speeds.rearRight);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-21 22:34:16 -07:00
|
|
|
TEST(MecanumDriveTest, Cartesian) {
|
2025-11-07 20:00:05 -05:00
|
|
|
wpi::MockPWMMotorController fl;
|
|
|
|
|
wpi::MockPWMMotorController rl;
|
|
|
|
|
wpi::MockPWMMotorController fr;
|
|
|
|
|
wpi::MockPWMMotorController rr;
|
|
|
|
|
wpi::MecanumDrive drive{[&](double output) { fl.Set(output); },
|
2024-01-01 13:37:51 -08:00
|
|
|
[&](double output) { rl.Set(output); },
|
|
|
|
|
[&](double output) { fr.Set(output); },
|
|
|
|
|
[&](double output) { rr.Set(output); }};
|
2021-05-21 22:34:16 -07:00
|
|
|
drive.SetDeadband(0.0);
|
|
|
|
|
|
|
|
|
|
// Forward
|
|
|
|
|
drive.DriveCartesian(1.0, 0.0, 0.0);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Left
|
|
|
|
|
drive.DriveCartesian(0.0, -1.0, 0.0);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Right
|
|
|
|
|
drive.DriveCartesian(0.0, 1.0, 0.0);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Rotate CCW
|
|
|
|
|
drive.DriveCartesian(0.0, 0.0, -1.0);
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fl.Get());
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rl.Get());
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Rotate CW
|
|
|
|
|
drive.DriveCartesian(0.0, 0.0, 1.0);
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fl.Get());
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rr.Get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(MecanumDriveTest, CartesianGyro90CW) {
|
2025-11-07 20:00:05 -05:00
|
|
|
wpi::MockPWMMotorController fl;
|
|
|
|
|
wpi::MockPWMMotorController rl;
|
|
|
|
|
wpi::MockPWMMotorController fr;
|
|
|
|
|
wpi::MockPWMMotorController rr;
|
|
|
|
|
wpi::MecanumDrive drive{[&](double output) { fl.Set(output); },
|
2024-01-01 13:37:51 -08:00
|
|
|
[&](double output) { rl.Set(output); },
|
|
|
|
|
[&](double output) { fr.Set(output); },
|
|
|
|
|
[&](double output) { rr.Set(output); }};
|
2021-05-21 22:34:16 -07:00
|
|
|
drive.SetDeadband(0.0);
|
|
|
|
|
|
|
|
|
|
// Forward in global frame; left in robot frame
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DriveCartesian(1.0, 0.0, 0.0, 90_deg);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Left in global frame; backward in robot frame
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DriveCartesian(0.0, -1.0, 0.0, 90_deg);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Right in global frame; forward in robot frame
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DriveCartesian(0.0, 1.0, 0.0, 90_deg);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Rotate CCW
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DriveCartesian(0.0, 0.0, -1.0, 90_deg);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fl.Get());
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rl.Get());
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Rotate CW
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DriveCartesian(0.0, 0.0, 1.0, 90_deg);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, fl.Get());
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rr.Get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(MecanumDriveTest, Polar) {
|
2025-11-07 20:00:05 -05:00
|
|
|
wpi::MockPWMMotorController fl;
|
|
|
|
|
wpi::MockPWMMotorController rl;
|
|
|
|
|
wpi::MockPWMMotorController fr;
|
|
|
|
|
wpi::MockPWMMotorController rr;
|
|
|
|
|
wpi::MecanumDrive drive{[&](double output) { fl.Set(output); },
|
2024-01-01 13:37:51 -08:00
|
|
|
[&](double output) { rl.Set(output); },
|
|
|
|
|
[&](double output) { fr.Set(output); },
|
|
|
|
|
[&](double output) { rr.Set(output); }};
|
2021-05-21 22:34:16 -07:00
|
|
|
drive.SetDeadband(0.0);
|
|
|
|
|
|
|
|
|
|
// Forward
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DrivePolar(1.0, 0_deg, 0.0);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Left
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DrivePolar(1.0, -90_deg, 0.0);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Right
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DrivePolar(1.0, 90_deg, 0.0);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, fl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rl.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Rotate CCW
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DrivePolar(0.0, 0_deg, -1.0);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fl.Get());
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rl.Get());
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, rr.Get());
|
|
|
|
|
|
|
|
|
|
// Rotate CW
|
2022-10-27 21:59:11 -07:00
|
|
|
drive.DrivePolar(0.0, 0_deg, 1.0);
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(1.0, fl.Get());
|
2022-02-17 18:03:59 -08:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, fr.Get());
|
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, rl.Get());
|
2021-05-21 22:34:16 -07:00
|
|
|
EXPECT_DOUBLE_EQ(-1.0, rr.Get());
|
|
|
|
|
}
|