Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame^] | 1 | /*----------------------------------------------------------------------------*/ |
| 2 | /* Copyright (c) FIRST 2014. All Rights Reserved. */ |
| 3 | /* Open Source Software - may be modified and shared by FRC teams. The code */ |
| 4 | /* must be accompanied by the FIRST BSD license file in the root directory of */ |
| 5 | /* the project. */ |
| 6 | /*----------------------------------------------------------------------------*/ |
| 7 | |
| 8 | #include <AnalogOutput.h> |
| 9 | #include <DigitalOutput.h> |
| 10 | #include <CANJaguar.h> |
| 11 | #include <Relay.h> |
| 12 | #include <Timer.h> |
| 13 | #include <WPIErrors.h> |
| 14 | #include "gtest/gtest.h" |
| 15 | #include "TestBench.h" |
| 16 | |
| 17 | static constexpr double kSpikeTime = 0.5; |
| 18 | |
| 19 | static constexpr double kExpectedBusVoltage = 14.0; |
| 20 | static constexpr double kExpectedTemperature = 25.0; |
| 21 | |
| 22 | static constexpr double kMotorTime = 0.5; |
| 23 | |
| 24 | static constexpr double kEncoderSettlingTime = 1.0; |
| 25 | static constexpr double kEncoderPositionTolerance = 0.1; |
| 26 | static constexpr double kEncoderSpeedTolerance = 30.0; |
| 27 | |
| 28 | static constexpr double kPotentiometerSettlingTime = 1.0; |
| 29 | static constexpr double kPotentiometerPositionTolerance = 0.1; |
| 30 | |
| 31 | static constexpr double kCurrentTolerance = 0.1; |
| 32 | |
| 33 | static constexpr double kVoltageTolerance = 0.1; |
| 34 | |
| 35 | static constexpr double kMotorVoltage = 5.0; |
| 36 | |
| 37 | static constexpr double kMotorPercent = 0.5; |
| 38 | |
| 39 | static constexpr double kMotorSpeed = 100; |
| 40 | class CANJaguarTest : public testing::Test { |
| 41 | protected: |
| 42 | CANJaguar *m_jaguar; |
| 43 | DigitalOutput *m_fakeForwardLimit, *m_fakeReverseLimit; |
| 44 | AnalogOutput *m_fakePotentiometer; |
| 45 | Relay *m_spike; |
| 46 | |
| 47 | virtual void SetUp() override { |
| 48 | m_spike = new Relay(TestBench::kCANJaguarRelayChannel, Relay::kForwardOnly); |
| 49 | m_spike->Set(Relay::kOn); |
| 50 | Wait(kSpikeTime); |
| 51 | |
| 52 | m_jaguar = new CANJaguar(TestBench::kCANJaguarID); |
| 53 | |
| 54 | m_fakeForwardLimit = new DigitalOutput(TestBench::kFakeJaguarForwardLimit); |
| 55 | m_fakeForwardLimit->Set(0); |
| 56 | |
| 57 | m_fakeReverseLimit = new DigitalOutput(TestBench::kFakeJaguarReverseLimit); |
| 58 | m_fakeReverseLimit->Set(0); |
| 59 | |
| 60 | m_fakePotentiometer = new AnalogOutput(TestBench::kFakeJaguarPotentiometer); |
| 61 | m_fakePotentiometer->SetVoltage(0.0f); |
| 62 | |
| 63 | /* The motor might still have momentum from the previous test. */ |
| 64 | Wait(kEncoderSettlingTime); |
| 65 | } |
| 66 | |
| 67 | virtual void TearDown() override { |
| 68 | delete m_jaguar; |
| 69 | delete m_fakeForwardLimit; |
| 70 | delete m_fakeReverseLimit; |
| 71 | delete m_fakePotentiometer; |
| 72 | delete m_spike; |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | * Calls CANJaguar::Set periodically 50 times to make sure everything is |
| 77 | * verified. This mimics a real robot program, where Set is presumably |
| 78 | * called in each iteration of the main loop. |
| 79 | */ |
| 80 | void SetJaguar(float totalTime, float value = 0.0f) { |
| 81 | for (int i = 0; i < 50; i++) { |
| 82 | m_jaguar->Set(value); |
| 83 | Wait(totalTime / 50.0); |
| 84 | } |
| 85 | } |
| 86 | /** |
| 87 | * returns the sign of the given number |
| 88 | */ |
| 89 | int SignNum(double value) { return -(value < 0) + (value > 0); } |
| 90 | void InversionTest(float motorValue, float delayTime = kMotorTime) { |
| 91 | m_jaguar->EnableControl(); |
| 92 | m_jaguar->SetInverted(false); |
| 93 | SetJaguar(delayTime, motorValue); |
| 94 | double initialSpeed = m_jaguar->GetSpeed(); |
| 95 | m_jaguar->Set(0.0); |
| 96 | m_jaguar->SetInverted(true); |
| 97 | SetJaguar(delayTime, motorValue); |
| 98 | double finalSpeed = m_jaguar->GetSpeed(); |
| 99 | // checks that the motor has changed direction |
| 100 | EXPECT_FALSE(SignNum(initialSpeed) == SignNum(finalSpeed)) |
| 101 | << "CAN Jaguar did not invert direction positive. Initial speed was: " |
| 102 | << initialSpeed << " Final displacement was: " << finalSpeed |
| 103 | << " Sign of initial displacement was: " << SignNum(initialSpeed) |
| 104 | << " Sign of final displacement was: " << SignNum(finalSpeed); |
| 105 | SetJaguar(delayTime, -motorValue); |
| 106 | initialSpeed = m_jaguar->GetSpeed(); |
| 107 | m_jaguar->Set(0.0); |
| 108 | m_jaguar->SetInverted(false); |
| 109 | SetJaguar(delayTime, -motorValue); |
| 110 | finalSpeed = m_jaguar->GetSpeed(); |
| 111 | EXPECT_FALSE(SignNum(initialSpeed) == SignNum(finalSpeed)) |
| 112 | << "CAN Jaguar did not invert direction negative. Initial displacement " |
| 113 | "was: " << initialSpeed << " Final displacement was: " << finalSpeed |
| 114 | << " Sign of initial displacement was: " << SignNum(initialSpeed) |
| 115 | << " Sign of final displacement was: " << SignNum(finalSpeed); |
| 116 | } |
| 117 | }; |
| 118 | |
| 119 | /** |
| 120 | * Tests that allocating the same CANJaguar port as an already allocated port |
| 121 | * causes a ResourceAlreadyAllocated error. |
| 122 | */ |
| 123 | TEST_F(CANJaguarTest, AlreadyAllocatedError) { |
| 124 | std::cout << "The following errors are expected." << std::endl |
| 125 | << std::endl; |
| 126 | |
| 127 | CANJaguar jaguar(TestBench::kCANJaguarID); |
| 128 | EXPECT_EQ(wpi_error_value_ResourceAlreadyAllocated, |
| 129 | jaguar.GetError().GetCode()) |
| 130 | << "An error should have been returned"; |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * Test that allocating a CANJaguar with device number 64 causes an |
| 135 | * out-of-range error. |
| 136 | */ |
| 137 | TEST_F(CANJaguarTest, 64OutOfRangeError) { |
| 138 | std::cout << "The following errors are expected." << std::endl |
| 139 | << std::endl; |
| 140 | |
| 141 | CANJaguar jaguar(64); |
| 142 | EXPECT_EQ(wpi_error_value_ChannelIndexOutOfRange, jaguar.GetError().GetCode()) |
| 143 | << "An error should have been returned"; |
| 144 | } |
| 145 | |
| 146 | /** |
| 147 | * Test that allocating a CANJaguar with device number 0 causes an out-of-range |
| 148 | * error. |
| 149 | */ |
| 150 | TEST_F(CANJaguarTest, 0OutOfRangeError) { |
| 151 | std::cout << "The following errors are expected." << std::endl |
| 152 | << std::endl; |
| 153 | |
| 154 | CANJaguar jaguar(0); |
| 155 | EXPECT_EQ(wpi_error_value_ChannelIndexOutOfRange, jaguar.GetError().GetCode()) |
| 156 | << "An error should have been returned"; |
| 157 | } |
| 158 | |
| 159 | /** |
| 160 | * Checks the default status data for reasonable values to confirm that we're |
| 161 | * really getting status data from the Jaguar. |
| 162 | */ |
| 163 | TEST_F(CANJaguarTest, InitialStatus) { |
| 164 | m_jaguar->SetPercentMode(); |
| 165 | |
| 166 | EXPECT_NEAR(m_jaguar->GetBusVoltage(), kExpectedBusVoltage, 3.0) |
| 167 | << "Bus voltage is not a plausible value."; |
| 168 | |
| 169 | EXPECT_FLOAT_EQ(m_jaguar->GetOutputVoltage(), 0.0) |
| 170 | << "Output voltage is non-zero."; |
| 171 | |
| 172 | EXPECT_FLOAT_EQ(m_jaguar->GetOutputCurrent(), 0.0) |
| 173 | << "Output current is non-zero."; |
| 174 | |
| 175 | EXPECT_NEAR(m_jaguar->GetTemperature(), kExpectedTemperature, 5.0) |
| 176 | << "Temperature is not a plausible value."; |
| 177 | |
| 178 | EXPECT_EQ(m_jaguar->GetFaults(), 0) << "Jaguar has one or more fault set."; |
| 179 | } |
| 180 | |
| 181 | /** |
| 182 | * Ensure that the jaguar doesn't move when it's disabled |
| 183 | */ |
| 184 | TEST_F(CANJaguarTest, Disable) { |
| 185 | m_jaguar->SetPercentMode(CANJaguar::QuadEncoder, 360); |
| 186 | m_jaguar->EnableControl(); |
| 187 | m_jaguar->DisableControl(); |
| 188 | |
| 189 | Wait(kEncoderSettlingTime); |
| 190 | |
| 191 | double initialPosition = m_jaguar->GetPosition(); |
| 192 | |
| 193 | SetJaguar(kMotorTime, 1.0f); |
| 194 | m_jaguar->Set(0.0f); |
| 195 | |
| 196 | double finalPosition = m_jaguar->GetPosition(); |
| 197 | |
| 198 | EXPECT_NEAR(initialPosition, finalPosition, kEncoderPositionTolerance) |
| 199 | << "Jaguar moved while disabled"; |
| 200 | } |
| 201 | |
| 202 | /** |
| 203 | * Make sure the Jaguar keeps its state after a power cycle by setting a |
| 204 | * control mode, turning the spike on and off, then checking if the Jaguar |
| 205 | * behaves like it should in that control mode. |
| 206 | */ |
| 207 | TEST_F(CANJaguarTest, BrownOut) { |
| 208 | /* Set the jaguar to quad encoder position mode */ |
| 209 | m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 20.0f, 0.01f, 0.0f); |
| 210 | m_jaguar->EnableControl(); |
| 211 | SetJaguar(kMotorTime, 0.0); |
| 212 | double setpoint = m_jaguar->GetPosition() + 1.0f; |
| 213 | |
| 214 | /* Turn the spike off and on again */ |
| 215 | m_spike->Set(Relay::kOff); |
| 216 | Wait(kSpikeTime); |
| 217 | m_spike->Set(Relay::kOn); |
| 218 | Wait(kSpikeTime); |
| 219 | |
| 220 | /* The jaguar should automatically get set to quad encoder position mode, |
| 221 | so it should be able to reach a setpoint in a couple seconds. */ |
| 222 | for (int i = 0; i < 10; i++) { |
| 223 | SetJaguar(1.0f, setpoint); |
| 224 | |
| 225 | if (std::abs(m_jaguar->GetPosition() - setpoint) <= |
| 226 | kEncoderPositionTolerance) { |
| 227 | return; |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | EXPECT_NEAR(setpoint, m_jaguar->GetPosition(), kEncoderPositionTolerance) |
| 232 | << "CAN Jaguar should have resumed PID control after power cycle"; |
| 233 | } |
| 234 | |
| 235 | /** |
| 236 | * Test if we can set arbitrary setpoints and PID values each each applicable |
| 237 | * mode and get the same values back. |
| 238 | */ |
| 239 | TEST_F(CANJaguarTest, SetGet) { |
| 240 | m_jaguar->DisableControl(); |
| 241 | |
| 242 | m_jaguar->SetSpeedMode(CANJaguar::QuadEncoder, 360, 1, 2, 3); |
| 243 | m_jaguar->Set(4); |
| 244 | |
| 245 | EXPECT_FLOAT_EQ(1, m_jaguar->GetP()); |
| 246 | EXPECT_FLOAT_EQ(2, m_jaguar->GetI()); |
| 247 | EXPECT_FLOAT_EQ(3, m_jaguar->GetD()); |
| 248 | EXPECT_FLOAT_EQ(4, m_jaguar->Get()); |
| 249 | } |
| 250 | |
| 251 | /** |
| 252 | * Test if we can drive the motor in percentage mode and get a position back |
| 253 | */ |
| 254 | TEST_F(CANJaguarTest, PercentModeForwardWorks) { |
| 255 | m_jaguar->SetPercentMode(CANJaguar::QuadEncoder, 360); |
| 256 | m_jaguar->EnableControl(); |
| 257 | |
| 258 | /* The motor might still have momentum from the previous test. */ |
| 259 | SetJaguar(kEncoderSettlingTime, 0.0f); |
| 260 | |
| 261 | double initialPosition = m_jaguar->GetPosition(); |
| 262 | |
| 263 | /* Drive the speed controller briefly to move the encoder */ |
| 264 | SetJaguar(kMotorTime, 1.0f); |
| 265 | m_jaguar->Set(0.0f); |
| 266 | |
| 267 | /* The position should have increased */ |
| 268 | EXPECT_GT(m_jaguar->GetPosition(), initialPosition) |
| 269 | << "CAN Jaguar position should have increased after the motor moved"; |
| 270 | } |
| 271 | |
| 272 | /** |
| 273 | * Test if we can drive the motor backwards in percentage mode and get a |
| 274 | * position back |
| 275 | */ |
| 276 | TEST_F(CANJaguarTest, PercentModeReverseWorks) { |
| 277 | m_jaguar->SetPercentMode(CANJaguar::QuadEncoder, 360); |
| 278 | m_jaguar->EnableControl(); |
| 279 | |
| 280 | /* The motor might still have momentum from the previous test. */ |
| 281 | SetJaguar(kEncoderSettlingTime, 0.0f); |
| 282 | |
| 283 | double initialPosition = m_jaguar->GetPosition(); |
| 284 | |
| 285 | /* Drive the speed controller briefly to move the encoder */ |
| 286 | SetJaguar(kMotorTime, -1.0f); |
| 287 | m_jaguar->Set(0.0f); |
| 288 | |
| 289 | float p = m_jaguar->GetPosition(); |
| 290 | /* The position should have decreased */ |
| 291 | EXPECT_LT(p, initialPosition) |
| 292 | << "CAN Jaguar position should have decreased after the motor moved"; |
| 293 | } |
| 294 | |
| 295 | /** |
| 296 | * Test if we can set an absolute voltage and receive a matching output voltage |
| 297 | * status. |
| 298 | */ |
| 299 | TEST_F(CANJaguarTest, VoltageModeWorks) { |
| 300 | m_jaguar->SetVoltageMode(); |
| 301 | m_jaguar->EnableControl(); |
| 302 | |
| 303 | float setpoints[] = {M_PI, 8.0f, -10.0f}; |
| 304 | |
| 305 | for (auto setpoint : setpoints) { |
| 306 | SetJaguar(kMotorTime, setpoint); |
| 307 | EXPECT_NEAR(setpoint, m_jaguar->GetOutputVoltage(), kVoltageTolerance); |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | /** |
| 312 | * Test if we can set a speed in speed control mode and receive a matching |
| 313 | * speed status. |
| 314 | */ |
| 315 | TEST_F(CANJaguarTest, SpeedModeWorks) { |
| 316 | m_jaguar->SetSpeedMode(CANJaguar::QuadEncoder, 360, 0.1f, 0.003f, 0.01f); |
| 317 | m_jaguar->EnableControl(); |
| 318 | |
| 319 | constexpr float speed = 50.0f; |
| 320 | |
| 321 | SetJaguar(kMotorTime, speed); |
| 322 | EXPECT_NEAR(speed, m_jaguar->GetSpeed(), kEncoderSpeedTolerance); |
| 323 | } |
| 324 | |
| 325 | /** |
| 326 | * Test if we can set a position and reach that position with PID control on |
| 327 | * the Jaguar. |
| 328 | */ |
| 329 | TEST_F(CANJaguarTest, PositionModeWorks) { |
| 330 | m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 15.0f, 0.02f, 0.0f); |
| 331 | |
| 332 | double setpoint = m_jaguar->GetPosition() + 1.0f; |
| 333 | |
| 334 | m_jaguar->EnableControl(); |
| 335 | |
| 336 | /* It should get to the setpoint within 10 seconds */ |
| 337 | for (int i = 0; i < 10; i++) { |
| 338 | SetJaguar(1.0f, setpoint); |
| 339 | |
| 340 | if (std::abs(m_jaguar->GetPosition() - setpoint) <= |
| 341 | kEncoderPositionTolerance) { |
| 342 | return; |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | EXPECT_NEAR(setpoint, m_jaguar->GetPosition(), kEncoderPositionTolerance) |
| 347 | << "CAN Jaguar should have reached setpoint with PID control"; |
| 348 | } |
| 349 | |
| 350 | /** |
| 351 | * Test if we can set a current setpoint with PID control on the Jaguar and get |
| 352 | * a corresponding output current |
| 353 | */ |
| 354 | TEST_F(CANJaguarTest, DISABLED_CurrentModeWorks) { |
| 355 | m_jaguar->SetCurrentMode(10.0, 4.0, 1.0); |
| 356 | m_jaguar->EnableControl(); |
| 357 | |
| 358 | float setpoints[] = {1.6f, 2.0f, -1.6f}; |
| 359 | |
| 360 | for (auto& setpoints_i : setpoints) { |
| 361 | float setpoint = setpoints_i; |
| 362 | float expectedCurrent = std::abs(setpoints_i); |
| 363 | |
| 364 | /* It should get to each setpoint within 10 seconds */ |
| 365 | for (int j = 0; j < 10; j++) { |
| 366 | SetJaguar(1.0, setpoint); |
| 367 | |
| 368 | if (std::abs(m_jaguar->GetOutputCurrent() - expectedCurrent) <= |
| 369 | kCurrentTolerance) { |
| 370 | break; |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | EXPECT_NEAR(expectedCurrent, m_jaguar->GetOutputCurrent(), |
| 375 | kCurrentTolerance); |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | /** |
| 380 | * Test if we can get a position in potentiometer mode, using an analog output |
| 381 | * as a fake potentiometer. |
| 382 | */ |
| 383 | TEST_F(CANJaguarTest, FakePotentiometerPosition) { |
| 384 | m_jaguar->SetPercentMode(CANJaguar::Potentiometer); |
| 385 | m_jaguar->EnableControl(); |
| 386 | |
| 387 | // Set the analog output to 4 different voltages and check if the Jaguar |
| 388 | // returns corresponding positions. |
| 389 | for (int i = 0; i <= 3; i++) { |
| 390 | m_fakePotentiometer->SetVoltage(static_cast<float>(i)); |
| 391 | |
| 392 | SetJaguar(kPotentiometerSettlingTime); |
| 393 | |
| 394 | EXPECT_NEAR(m_fakePotentiometer->GetVoltage() / 3.0f, |
| 395 | m_jaguar->GetPosition(), kPotentiometerPositionTolerance) |
| 396 | << "CAN Jaguar should have returned the potentiometer position set by " |
| 397 | "the analog output"; |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | /** |
| 402 | * Test if we can limit the Jaguar to only moving in reverse with a fake |
| 403 | * limit switch. |
| 404 | */ |
| 405 | TEST_F(CANJaguarTest, FakeLimitSwitchForwards) { |
| 406 | m_jaguar->SetPercentMode(CANJaguar::QuadEncoder, 360); |
| 407 | m_jaguar->ConfigLimitMode(CANJaguar::kLimitMode_SwitchInputsOnly); |
| 408 | m_fakeForwardLimit->Set(1); |
| 409 | m_fakeReverseLimit->Set(0); |
| 410 | m_jaguar->EnableControl(); |
| 411 | |
| 412 | SetJaguar(kEncoderSettlingTime); |
| 413 | |
| 414 | /* Make sure the limits are recognized by the Jaguar. */ |
| 415 | ASSERT_FALSE(m_jaguar->GetForwardLimitOK()); |
| 416 | ASSERT_TRUE(m_jaguar->GetReverseLimitOK()); |
| 417 | |
| 418 | double initialPosition = m_jaguar->GetPosition(); |
| 419 | |
| 420 | /* Drive the speed controller briefly to move the encoder. If the limit |
| 421 | switch is recognized, it shouldn't actually move. */ |
| 422 | SetJaguar(kMotorTime, 1.0f); |
| 423 | |
| 424 | /* The position should be the same, since the limit switch was on. */ |
| 425 | EXPECT_NEAR(initialPosition, m_jaguar->GetPosition(), |
| 426 | kEncoderPositionTolerance) |
| 427 | << "CAN Jaguar should not have moved with the limit switch pressed"; |
| 428 | |
| 429 | /* Drive the speed controller in the other direction. It should actually |
| 430 | move, since only the forward switch is activated.*/ |
| 431 | SetJaguar(kMotorTime, -1.0f); |
| 432 | |
| 433 | /* The position should have decreased */ |
| 434 | EXPECT_LT(m_jaguar->GetPosition(), initialPosition) |
| 435 | << "CAN Jaguar should have moved in reverse while the forward limit was " |
| 436 | "on"; |
| 437 | } |
| 438 | |
| 439 | /** |
| 440 | * Test if we can limit the Jaguar to only moving forwards with a fake limit |
| 441 | * switch. |
| 442 | */ |
| 443 | TEST_F(CANJaguarTest, FakeLimitSwitchReverse) { |
| 444 | m_jaguar->SetPercentMode(CANJaguar::QuadEncoder, 360); |
| 445 | m_jaguar->ConfigLimitMode(CANJaguar::kLimitMode_SwitchInputsOnly); |
| 446 | m_fakeForwardLimit->Set(0); |
| 447 | m_fakeReverseLimit->Set(1); |
| 448 | m_jaguar->EnableControl(); |
| 449 | |
| 450 | SetJaguar(kEncoderSettlingTime); |
| 451 | |
| 452 | /* Make sure the limits are recognized by the Jaguar. */ |
| 453 | ASSERT_TRUE(m_jaguar->GetForwardLimitOK()); |
| 454 | ASSERT_FALSE(m_jaguar->GetReverseLimitOK()); |
| 455 | |
| 456 | double initialPosition = m_jaguar->GetPosition(); |
| 457 | |
| 458 | /* Drive the speed controller backwards briefly to move the encoder. If |
| 459 | the limit switch is recognized, it shouldn't actually move. */ |
| 460 | SetJaguar(kMotorTime, -1.0f); |
| 461 | |
| 462 | /* The position should be the same, since the limit switch was on. */ |
| 463 | EXPECT_NEAR(initialPosition, m_jaguar->GetPosition(), |
| 464 | kEncoderPositionTolerance) |
| 465 | << "CAN Jaguar should not have moved with the limit switch pressed"; |
| 466 | |
| 467 | /* Drive the speed controller in the other direction. It should actually |
| 468 | move, since only the reverse switch is activated.*/ |
| 469 | SetJaguar(kMotorTime, 1.0f); |
| 470 | |
| 471 | /* The position should have increased */ |
| 472 | EXPECT_GT(m_jaguar->GetPosition(), initialPosition) |
| 473 | << "CAN Jaguar should have moved forwards while the reverse limit was on"; |
| 474 | } |
| 475 | /** |
| 476 | * Tests that inversion works in voltage mode |
| 477 | */ |
| 478 | TEST_F(CANJaguarTest, InvertingVoltageMode) { |
| 479 | m_jaguar->SetVoltageMode(CANJaguar::QuadEncoder, 360); |
| 480 | m_jaguar->EnableControl(); |
| 481 | InversionTest(kMotorVoltage); |
| 482 | } |
| 483 | |
| 484 | /** |
| 485 | * Tests that inversion works in percentMode |
| 486 | */ |
| 487 | TEST_F(CANJaguarTest, InvertingPercentMode) { |
| 488 | m_jaguar->SetPercentMode(CANJaguar::QuadEncoder, 360); |
| 489 | m_jaguar->EnableControl(); |
| 490 | InversionTest(kMotorPercent); |
| 491 | } |
| 492 | /** |
| 493 | * Tests that inversion works in SpeedMode |
| 494 | */ |
| 495 | TEST_F(CANJaguarTest, InvertingSpeedMode) { |
| 496 | m_jaguar->SetSpeedMode(CANJaguar::QuadEncoder, 360, 0.1f, 0.005f, 0.00f); |
| 497 | m_jaguar->EnableControl(); |
| 498 | InversionTest(kMotorSpeed, kMotorTime); |
| 499 | } |