[wpilib] Check for signedness in ArcadeDriveIK() (#4028)

If xSpeed == -0.0 and zRotation > 0, the algorithm assumes it's in the
third quadrant instead of the first since +0.0 == -0.0.

Also added tests for inverse kinematic functions, fixed some
MecanumDrive test bugs, and added Java MecanumDrive.driveCartesianIK()
and KilloughDrive.driveCartesianIK() overloads with defaulted gyro angle
that C++ already had.

Fixes #4022.
This commit is contained in:
Tyler Veness
2022-02-17 18:03:59 -08:00
committed by GitHub
parent a19d1133b1
commit 49adac9564
10 changed files with 844 additions and 39 deletions

View File

@@ -6,6 +6,238 @@
#include "frc/drive/DifferentialDrive.h"
#include "gtest/gtest.h"
TEST(DifferentialDriveTest, ArcadeDriveIK) {
// Forward
auto speeds = frc::DifferentialDrive::ArcadeDriveIK(1.0, 0.0, false);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward left turn
speeds = frc::DifferentialDrive::ArcadeDriveIK(0.5, -0.5, false);
EXPECT_DOUBLE_EQ(0.0, speeds.left);
EXPECT_DOUBLE_EQ(0.5, speeds.right);
// Forward right turn
speeds = frc::DifferentialDrive::ArcadeDriveIK(0.5, 0.5, false);
EXPECT_DOUBLE_EQ(0.5, speeds.left);
EXPECT_DOUBLE_EQ(0.0, speeds.right);
// Backward
speeds = frc::DifferentialDrive::ArcadeDriveIK(-1.0, 0.0, false);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Backward left turn
speeds = frc::DifferentialDrive::ArcadeDriveIK(-0.5, -0.5, false);
EXPECT_DOUBLE_EQ(-0.5, speeds.left);
EXPECT_DOUBLE_EQ(0.0, speeds.right);
// Backward right turn
speeds = frc::DifferentialDrive::ArcadeDriveIK(-0.5, 0.5, false);
EXPECT_DOUBLE_EQ(0.0, speeds.left);
EXPECT_DOUBLE_EQ(-0.5, speeds.right);
// Left turn (xSpeed with negative sign)
speeds = frc::DifferentialDrive::ArcadeDriveIK(-0.0, -1.0, false);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Left turn (xSpeed with positive sign)
speeds = frc::DifferentialDrive::ArcadeDriveIK(0.0, -1.0, false);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Right turn (xSpeed with negative sign)
speeds = frc::DifferentialDrive::ArcadeDriveIK(-0.0, 1.0, false);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Right turn (xSpeed with positive sign)
speeds = frc::DifferentialDrive::ArcadeDriveIK(0.0, 1.0, false);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
}
TEST(DifferentialDriveTest, ArcadeDriveIKSquared) {
// Forward
auto speeds = frc::DifferentialDrive::ArcadeDriveIK(1.0, 0.0, true);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward left turn
speeds = frc::DifferentialDrive::ArcadeDriveIK(0.5, -0.5, true);
EXPECT_DOUBLE_EQ(0.0, speeds.left);
EXPECT_DOUBLE_EQ(0.25, speeds.right);
// Forward right turn
speeds = frc::DifferentialDrive::ArcadeDriveIK(0.5, 0.5, true);
EXPECT_DOUBLE_EQ(0.25, speeds.left);
EXPECT_DOUBLE_EQ(0.0, speeds.right);
// Backward
speeds = frc::DifferentialDrive::ArcadeDriveIK(-1.0, 0.0, true);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Backward left turn
speeds = frc::DifferentialDrive::ArcadeDriveIK(-0.5, -0.5, true);
EXPECT_DOUBLE_EQ(-0.25, speeds.left);
EXPECT_DOUBLE_EQ(0.0, speeds.right);
// Backward right turn
speeds = frc::DifferentialDrive::ArcadeDriveIK(-0.5, 0.5, true);
EXPECT_DOUBLE_EQ(0.0, speeds.left);
EXPECT_DOUBLE_EQ(-0.25, speeds.right);
// Left turn (xSpeed with negative sign)
speeds = frc::DifferentialDrive::ArcadeDriveIK(-0.0, -1.0, false);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Left turn (xSpeed with positive sign)
speeds = frc::DifferentialDrive::ArcadeDriveIK(0.0, -1.0, false);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Right turn (xSpeed with negative sign)
speeds = frc::DifferentialDrive::ArcadeDriveIK(-0.0, 1.0, false);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Right turn (xSpeed with positive sign)
speeds = frc::DifferentialDrive::ArcadeDriveIK(0.0, 1.0, false);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
}
TEST(DifferentialDriveTest, CurvatureDriveIK) {
// Forward
auto speeds = frc::DifferentialDrive::CurvatureDriveIK(1.0, 0.0, false);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward left turn
speeds = frc::DifferentialDrive::CurvatureDriveIK(0.5, -0.5, false);
EXPECT_DOUBLE_EQ(0.25, speeds.left);
EXPECT_DOUBLE_EQ(0.75, speeds.right);
// Forward right turn
speeds = frc::DifferentialDrive::CurvatureDriveIK(0.5, 0.5, false);
EXPECT_DOUBLE_EQ(0.75, speeds.left);
EXPECT_DOUBLE_EQ(0.25, speeds.right);
// Backward
speeds = frc::DifferentialDrive::CurvatureDriveIK(-1.0, 0.0, false);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Backward left turn
speeds = frc::DifferentialDrive::CurvatureDriveIK(-0.5, -0.5, false);
EXPECT_DOUBLE_EQ(-0.75, speeds.left);
EXPECT_DOUBLE_EQ(-0.25, speeds.right);
// Backward right turn
speeds = frc::DifferentialDrive::CurvatureDriveIK(-0.5, 0.5, false);
EXPECT_DOUBLE_EQ(-0.25, speeds.left);
EXPECT_DOUBLE_EQ(-0.75, speeds.right);
}
TEST(DifferentialDriveTest, CurvatureDriveIKTurnInPlace) {
// Forward
auto speeds = frc::DifferentialDrive::CurvatureDriveIK(1.0, 0.0, true);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward left turn
speeds = frc::DifferentialDrive::CurvatureDriveIK(0.5, -0.5, true);
EXPECT_DOUBLE_EQ(0.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward right turn
speeds = frc::DifferentialDrive::CurvatureDriveIK(0.5, 0.5, true);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(0.0, speeds.right);
// Backward
speeds = frc::DifferentialDrive::CurvatureDriveIK(-1.0, 0.0, true);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Backward left turn
speeds = frc::DifferentialDrive::CurvatureDriveIK(-0.5, -0.5, true);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(0.0, speeds.right);
// Backward right turn
speeds = frc::DifferentialDrive::CurvatureDriveIK(-0.5, 0.5, true);
EXPECT_DOUBLE_EQ(0.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
}
TEST(DifferentialDriveTest, TankDriveIK) {
// Forward
auto speeds = frc::DifferentialDrive::TankDriveIK(1.0, 1.0, false);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward left turn
speeds = frc::DifferentialDrive::TankDriveIK(0.5, 1.0, false);
EXPECT_DOUBLE_EQ(0.5, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward right turn
speeds = frc::DifferentialDrive::TankDriveIK(1.0, 0.5, false);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(0.5, speeds.right);
// Backward
speeds = frc::DifferentialDrive::TankDriveIK(-1.0, -1.0, false);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Backward left turn
speeds = frc::DifferentialDrive::TankDriveIK(-0.5, -1.0, false);
EXPECT_DOUBLE_EQ(-0.5, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Backward right turn
speeds = frc::DifferentialDrive::TankDriveIK(-0.5, 1.0, false);
EXPECT_DOUBLE_EQ(-0.5, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
}
TEST(DifferentialDriveTest, TankDriveIKSquared) {
// Forward
auto speeds = frc::DifferentialDrive::TankDriveIK(1.0, 1.0, true);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward left turn
speeds = frc::DifferentialDrive::TankDriveIK(0.5, 1.0, true);
EXPECT_DOUBLE_EQ(0.25, speeds.left);
EXPECT_DOUBLE_EQ(1.0, speeds.right);
// Forward right turn
speeds = frc::DifferentialDrive::TankDriveIK(1.0, 0.5, true);
EXPECT_DOUBLE_EQ(1.0, speeds.left);
EXPECT_DOUBLE_EQ(0.25, speeds.right);
// Backward
speeds = frc::DifferentialDrive::TankDriveIK(-1.0, -1.0, true);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Backward left turn
speeds = frc::DifferentialDrive::TankDriveIK(-0.5, -1.0, true);
EXPECT_DOUBLE_EQ(-0.25, speeds.left);
EXPECT_DOUBLE_EQ(-1.0, speeds.right);
// Backward right turn
speeds = frc::DifferentialDrive::TankDriveIK(-1.0, -0.5, true);
EXPECT_DOUBLE_EQ(-1.0, speeds.left);
EXPECT_DOUBLE_EQ(-0.25, speeds.right);
}
TEST(DifferentialDriveTest, ArcadeDrive) {
frc::MockMotorController left;
frc::MockMotorController right;