001/* 002 * Copyright (C) Cross The Road Electronics. All rights reserved. 003 * License information can be found in CTRE_LICENSE.txt 004 * For support and suggestions contact support@ctr-electronics.com or file 005 * an issue tracker at https://github.com/CrossTheRoadElec/Phoenix-Releases 006 */ 007package com.ctre.phoenix6.swerve; 008 009import static edu.wpi.first.units.Units.*; 010 011import java.util.HashMap; 012 013import com.ctre.phoenix6.StatusCode; 014import com.ctre.phoenix6.controls.CoastOut; 015import com.ctre.phoenix6.controls.PositionTorqueCurrentFOC; 016import com.ctre.phoenix6.controls.PositionVoltage; 017import com.ctre.phoenix6.controls.VoltageOut; 018import com.ctre.phoenix6.swerve.SwerveDrivetrain.SwerveControlParameters; 019import com.ctre.phoenix6.swerve.jni.SwerveJNI; 020import com.ctre.phoenix6.swerve.utility.PhoenixPIDController; 021 022import edu.wpi.first.math.geometry.Rotation2d; 023import edu.wpi.first.math.geometry.Translation2d; 024import edu.wpi.first.math.kinematics.ChassisSpeeds; 025import edu.wpi.first.math.kinematics.SwerveDriveKinematics; 026import edu.wpi.first.units.measure.*; 027 028/** 029 * Container for all the Swerve Requests. Use this to find all applicable swerve 030 * drive requests. 031 * <p> 032 * This is also an interface common to all swerve drive control requests that 033 * allow the request to calculate the state to apply to the modules. 034 */ 035public interface SwerveRequest { 036 /** 037 * In field-centric control, the direction of "forward" is sometimes different 038 * depending on perspective. This addresses which forward to use. 039 */ 040 public enum ForwardPerspectiveValue { 041 /** 042 * "Forward" (positive X) is determined from the operator's perspective. This 043 * is important for most teleop driven field-centric requests, where positive 044 * X means to drive away from the operator. 045 * <p> 046 * Important: Users must specify the OperatorPerspective in the SwerveDrivetrain object 047 */ 048 OperatorPerspective(0), 049 /** 050 * "Forward" (positive X) is always from the perspective of the blue alliance (i.e. towards 051 * the red alliance). This is important in situations such as path following where positive 052 * X is always from the blue alliance perspective, regardless of where the operator is 053 * physically located. 054 */ 055 BlueAlliance(1); 056 057 public final int value; 058 059 ForwardPerspectiveValue(int initValue) { 060 this.value = initValue; 061 } 062 063 private static HashMap<Integer, ForwardPerspectiveValue> _map = null; 064 static { 065 _map = new HashMap<Integer, ForwardPerspectiveValue>(); 066 for (ForwardPerspectiveValue type : ForwardPerspectiveValue.values()) { 067 _map.put(type.value, type); 068 } 069 } 070 071 /** 072 * Gets ForwardPerspectiveValue from specified value 073 * 074 * @param value Value of ForwardPerspectiveValue 075 * @return ForwardPerspectiveValue of specified value 076 */ 077 public static ForwardPerspectiveValue valueOf(int value) { 078 ForwardPerspectiveValue retval = _map.get(value); 079 if (retval != null) 080 return retval; 081 return ForwardPerspectiveValue.values()[0]; 082 } 083 } 084 085 /** 086 * Applies this swerve request to the given modules. This is 087 * typically called by the SwerveDrivetrain odometry thread. 088 * <p> 089 * For native swerve requests, this API can be called from a 090 * non-native request's {@code apply} to compose the two together. 091 * 092 * @param parameters Parameters the control request needs to calculate the module state 093 * @param modulesToApply Modules to which the control request is applied 094 * @return Status code of sending the request 095 */ 096 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply); 097 098 /** Swerve requests implemented in native code. */ 099 public interface NativeSwerveRequest extends SwerveRequest { 100 /** 101 * Applies a native swerve request to the native drivetrain with the provided ID. 102 * <p> 103 * When this is implemented, the regular {@link #apply} function should do nothing 104 * (return OK). Additionally, this cannot be called from another swerve request's 105 * apply method, as this overrides the native swerve request of the drivetrain. 106 * <p> 107 * Unlike {@link #apply}, this function is called every time {@link SwerveDrivetrain#setControl} 108 * is run, not every loop of the odometry thread. Instead, the underlying native 109 * request is run at the full update frequency of the odometry thread. 110 * 111 * @param id ID of the native swerve drivetrain 112 */ 113 public void applyNative(int id); 114 } 115 116 117 /** 118 * Does nothing to the swerve module state. This is the default state of a newly 119 * created swerve drive mechanism. 120 */ 121 public static class Idle implements NativeSwerveRequest { 122 123 124 125 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 126 return StatusCode.valueOf(SwerveJNI.JNI_Request_Apply_Idle(parameters.drivetrainId)); 127 } 128 129 public void applyNative(int id) { 130 SwerveJNI.JNI_SetControl_Idle(id); 131 } 132 } 133 134 /** 135 * Sets the swerve drive module states to point inward on the robot in an "X" 136 * fashion, creating a natural brake which will oppose any motion. 137 */ 138 public static class SwerveDriveBrake implements NativeSwerveRequest { 139 /** 140 * The type of control request to use for the drive motor. 141 */ 142 public SwerveModule.DriveRequestType DriveRequestType = SwerveModule.DriveRequestType.OpenLoopVoltage; 143 /** 144 * The type of control request to use for the drive motor. 145 */ 146 public SwerveModule.SteerRequestType SteerRequestType = SwerveModule.SteerRequestType.Position; 147 148 /** 149 * Modifies the DriveRequestType parameter and returns itself. 150 * <p> 151 * The type of control request to use for the drive motor. 152 * 153 * @param newDriveRequestType Parameter to modify 154 * @return this object 155 */ 156 public SwerveDriveBrake withDriveRequestType(SwerveModule.DriveRequestType newDriveRequestType) { 157 this.DriveRequestType = newDriveRequestType; 158 return this; 159 } 160 161 /** 162 * Modifies the SteerRequestType parameter and returns itself. 163 * <p> 164 * The type of control request to use for the drive motor. 165 * 166 * @param newSteerRequestType Parameter to modify 167 * @return this object 168 */ 169 public SwerveDriveBrake withSteerRequestType(SwerveModule.SteerRequestType newSteerRequestType) { 170 this.SteerRequestType = newSteerRequestType; 171 return this; 172 } 173 174 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 175 return StatusCode.valueOf(SwerveJNI.JNI_Request_Apply_SwerveDriveBrake(parameters.drivetrainId, 176 DriveRequestType.value, 177 SteerRequestType.value)); 178 } 179 180 public void applyNative(int id) { 181 SwerveJNI.JNI_SetControl_SwerveDriveBrake(id, 182 DriveRequestType.value, 183 SteerRequestType.value); 184 } 185 } 186 187 /** 188 * Drives the swerve drivetrain in a field-centric manner. 189 * <p> 190 * When users use this request, they specify the direction the robot should 191 * travel oriented against the field, and the rate at which their robot should 192 * rotate about the center of the robot. 193 * <p> 194 * An example scenario is that the robot is oriented to the east, the VelocityX 195 * is +5 m/s, VelocityY is 0 m/s, and RotationRate is 0.5 rad/s. In this 196 * scenario, the robot would drive northward at 5 m/s and turn counterclockwise 197 * at 0.5 rad/s. 198 */ 199 public static class FieldCentric implements NativeSwerveRequest { 200 /** 201 * The velocity in the X direction, in m/s. X is defined as forward according to 202 * WPILib convention, so this determines how fast to travel forward. 203 */ 204 public double VelocityX = 0; 205 /** 206 * The velocity in the Y direction, in m/s. Y is defined as to the left 207 * according to WPILib convention, so this determines how fast to travel to the 208 * left. 209 */ 210 public double VelocityY = 0; 211 /** 212 * The angular rate to rotate at, in radians per second. Angular rate is defined 213 * as counterclockwise positive, so this determines how fast to turn 214 * counterclockwise. 215 */ 216 public double RotationalRate = 0; 217 /** 218 * The allowable deadband of the request, in m/s. 219 */ 220 public double Deadband = 0; 221 /** 222 * The rotational deadband of the request, in radians per second. 223 */ 224 public double RotationalDeadband = 0; 225 /** 226 * The center of rotation the robot should rotate around. This is (0,0) by 227 * default, which will rotate around the center of the robot. 228 */ 229 public Translation2d CenterOfRotation = new Translation2d(); 230 /** 231 * The type of control request to use for the drive motor. 232 */ 233 public SwerveModule.DriveRequestType DriveRequestType = SwerveModule.DriveRequestType.OpenLoopVoltage; 234 /** 235 * The type of control request to use for the drive motor. 236 */ 237 public SwerveModule.SteerRequestType SteerRequestType = SwerveModule.SteerRequestType.Position; 238 /** 239 * Whether to desaturate wheel speeds before applying. For more information, see 240 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 241 */ 242 public boolean DesaturateWheelSpeeds = true; 243 /** 244 * The perspective to use when determining which direction is forward. 245 */ 246 public ForwardPerspectiveValue ForwardPerspective = ForwardPerspectiveValue.OperatorPerspective; 247 248 /** 249 * Modifies the VelocityX parameter and returns itself. 250 * <p> 251 * The velocity in the X direction, in m/s. X is defined as forward according to 252 * WPILib convention, so this determines how fast to travel forward. 253 * 254 * @param newVelocityX Parameter to modify 255 * @return this object 256 */ 257 public FieldCentric withVelocityX(double newVelocityX) { 258 this.VelocityX = newVelocityX; 259 return this; 260 } 261 262 /** 263 * Modifies the VelocityX parameter and returns itself. 264 * <p> 265 * The velocity in the X direction, in m/s. X is defined as forward according to 266 * WPILib convention, so this determines how fast to travel forward. 267 * 268 * @param newVelocityX Parameter to modify 269 * @return this object 270 */ 271 public FieldCentric withVelocityX(LinearVelocity newVelocityX) { 272 this.VelocityX = newVelocityX.in(MetersPerSecond); 273 return this; 274 } 275 276 /** 277 * Modifies the VelocityY parameter and returns itself. 278 * <p> 279 * The velocity in the Y direction, in m/s. Y is defined as to the left 280 * according to WPILib convention, so this determines how fast to travel to the 281 * left. 282 * 283 * @param newVelocityY Parameter to modify 284 * @return this object 285 */ 286 public FieldCentric withVelocityY(double newVelocityY) { 287 this.VelocityY = newVelocityY; 288 return this; 289 } 290 291 /** 292 * Modifies the VelocityY parameter and returns itself. 293 * <p> 294 * The velocity in the Y direction, in m/s. Y is defined as to the left 295 * according to WPILib convention, so this determines how fast to travel to the 296 * left. 297 * 298 * @param newVelocityY Parameter to modify 299 * @return this object 300 */ 301 public FieldCentric withVelocityY(LinearVelocity newVelocityY) { 302 this.VelocityY = newVelocityY.in(MetersPerSecond); 303 return this; 304 } 305 306 /** 307 * Modifies the RotationalRate parameter and returns itself. 308 * <p> 309 * The angular rate to rotate at, in radians per second. Angular rate is defined 310 * as counterclockwise positive, so this determines how fast to turn 311 * counterclockwise. 312 * 313 * @param newRotationalRate Parameter to modify 314 * @return this object 315 */ 316 public FieldCentric withRotationalRate(double newRotationalRate) { 317 this.RotationalRate = newRotationalRate; 318 return this; 319 } 320 321 /** 322 * Modifies the RotationalRate parameter and returns itself. 323 * <p> 324 * The angular rate to rotate at, in radians per second. Angular rate is defined 325 * as counterclockwise positive, so this determines how fast to turn 326 * counterclockwise. 327 * 328 * @param newRotationalRate Parameter to modify 329 * @return this object 330 */ 331 public FieldCentric withRotationalRate(AngularVelocity newRotationalRate) { 332 this.RotationalRate = newRotationalRate.in(RadiansPerSecond); 333 return this; 334 } 335 336 /** 337 * Modifies the Deadband parameter and returns itself. 338 * <p> 339 * The allowable deadband of the request, in m/s. 340 * 341 * @param newDeadband Parameter to modify 342 * @return this object 343 */ 344 public FieldCentric withDeadband(double newDeadband) { 345 this.Deadband = newDeadband; 346 return this; 347 } 348 349 /** 350 * Modifies the Deadband parameter and returns itself. 351 * <p> 352 * The allowable deadband of the request, in m/s. 353 * 354 * @param newDeadband Parameter to modify 355 * @return this object 356 */ 357 public FieldCentric withDeadband(LinearVelocity newDeadband) { 358 this.Deadband = newDeadband.in(MetersPerSecond); 359 return this; 360 } 361 362 /** 363 * Modifies the RotationalDeadband parameter and returns itself. 364 * <p> 365 * The rotational deadband of the request, in radians per second. 366 * 367 * @param newRotationalDeadband Parameter to modify 368 * @return this object 369 */ 370 public FieldCentric withRotationalDeadband(double newRotationalDeadband) { 371 this.RotationalDeadband = newRotationalDeadband; 372 return this; 373 } 374 375 /** 376 * Modifies the RotationalDeadband parameter and returns itself. 377 * <p> 378 * The rotational deadband of the request, in radians per second. 379 * 380 * @param newRotationalDeadband Parameter to modify 381 * @return this object 382 */ 383 public FieldCentric withRotationalDeadband(AngularVelocity newRotationalDeadband) { 384 this.RotationalDeadband = newRotationalDeadband.in(RadiansPerSecond); 385 return this; 386 } 387 388 /** 389 * Modifies the CenterOfRotation parameter and returns itself. 390 * <p> 391 * The center of rotation the robot should rotate around. This is (0,0) by 392 * default, which will rotate around the center of the robot. 393 * 394 * @param newCenterOfRotation Parameter to modify 395 * @return this object 396 */ 397 public FieldCentric withCenterOfRotation(Translation2d newCenterOfRotation) { 398 this.CenterOfRotation = newCenterOfRotation; 399 return this; 400 } 401 402 /** 403 * Modifies the DriveRequestType parameter and returns itself. 404 * <p> 405 * The type of control request to use for the drive motor. 406 * 407 * @param newDriveRequestType Parameter to modify 408 * @return this object 409 */ 410 public FieldCentric withDriveRequestType(SwerveModule.DriveRequestType newDriveRequestType) { 411 this.DriveRequestType = newDriveRequestType; 412 return this; 413 } 414 415 /** 416 * Modifies the SteerRequestType parameter and returns itself. 417 * <p> 418 * The type of control request to use for the drive motor. 419 * 420 * @param newSteerRequestType Parameter to modify 421 * @return this object 422 */ 423 public FieldCentric withSteerRequestType(SwerveModule.SteerRequestType newSteerRequestType) { 424 this.SteerRequestType = newSteerRequestType; 425 return this; 426 } 427 428 /** 429 * Modifies the DesaturateWheelSpeeds parameter and returns itself. 430 * <p> 431 * Whether to desaturate wheel speeds before applying. For more information, see 432 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 433 * 434 * @param newDesaturateWheelSpeeds Parameter to modify 435 * @return this object 436 */ 437 public FieldCentric withDesaturateWheelSpeeds(boolean newDesaturateWheelSpeeds) { 438 this.DesaturateWheelSpeeds = newDesaturateWheelSpeeds; 439 return this; 440 } 441 442 /** 443 * Modifies the ForwardPerspective parameter and returns itself. 444 * <p> 445 * The perspective to use when determining which direction is forward. 446 * 447 * @param newForwardPerspective Parameter to modify 448 * @return this object 449 */ 450 public FieldCentric withForwardPerspective(ForwardPerspectiveValue newForwardPerspective) { 451 this.ForwardPerspective = newForwardPerspective; 452 return this; 453 } 454 455 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 456 return StatusCode.valueOf(SwerveJNI.JNI_Request_Apply_FieldCentric(parameters.drivetrainId, 457 VelocityX, 458 VelocityY, 459 RotationalRate, 460 Deadband, 461 RotationalDeadband, 462 CenterOfRotation.getX(), 463 CenterOfRotation.getY(), 464 DriveRequestType.value, 465 SteerRequestType.value, 466 DesaturateWheelSpeeds, 467 ForwardPerspective.value)); 468 } 469 470 public void applyNative(int id) { 471 SwerveJNI.JNI_SetControl_FieldCentric(id, 472 VelocityX, 473 VelocityY, 474 RotationalRate, 475 Deadband, 476 RotationalDeadband, 477 CenterOfRotation.getX(), 478 CenterOfRotation.getY(), 479 DriveRequestType.value, 480 SteerRequestType.value, 481 DesaturateWheelSpeeds, 482 ForwardPerspective.value); 483 } 484 } 485 486 /** 487 * Drives the swerve drivetrain in a robot-centric manner. 488 * <p> 489 * When users use this request, they specify the direction the robot should 490 * travel oriented against the robot itself, and the rate at which their robot 491 * should rotate about the center of the robot. 492 * <p> 493 * An example scenario is that the robot is oriented to the east, the VelocityX 494 * is +5 m/s, VelocityY is 0 m/s, and RotationRate is 0.5 rad/s. In this 495 * scenario, the robot would drive eastward at 5 m/s and turn counterclockwise 496 * at 0.5 rad/s. 497 */ 498 public static class RobotCentric implements NativeSwerveRequest { 499 /** 500 * The velocity in the X direction, in m/s. X is defined as forward according to 501 * WPILib convention, so this determines how fast to travel forward. 502 */ 503 public double VelocityX = 0; 504 /** 505 * The velocity in the Y direction, in m/s. Y is defined as to the left 506 * according to WPILib convention, so this determines how fast to travel to the 507 * left. 508 */ 509 public double VelocityY = 0; 510 /** 511 * The angular rate to rotate at, in radians per second. Angular rate is defined 512 * as counterclockwise positive, so this determines how fast to turn 513 * counterclockwise. 514 */ 515 public double RotationalRate = 0; 516 /** 517 * The allowable deadband of the request, in m/s. 518 */ 519 public double Deadband = 0; 520 /** 521 * The rotational deadband of the request, in radians per second. 522 */ 523 public double RotationalDeadband = 0; 524 /** 525 * The center of rotation the robot should rotate around. This is (0,0) by 526 * default, which will rotate around the center of the robot. 527 */ 528 public Translation2d CenterOfRotation = new Translation2d(); 529 /** 530 * The type of control request to use for the drive motor. 531 */ 532 public SwerveModule.DriveRequestType DriveRequestType = SwerveModule.DriveRequestType.OpenLoopVoltage; 533 /** 534 * The type of control request to use for the drive motor. 535 */ 536 public SwerveModule.SteerRequestType SteerRequestType = SwerveModule.SteerRequestType.Position; 537 /** 538 * Whether to desaturate wheel speeds before applying. For more information, see 539 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 540 */ 541 public boolean DesaturateWheelSpeeds = true; 542 543 /** 544 * Modifies the VelocityX parameter and returns itself. 545 * <p> 546 * The velocity in the X direction, in m/s. X is defined as forward according to 547 * WPILib convention, so this determines how fast to travel forward. 548 * 549 * @param newVelocityX Parameter to modify 550 * @return this object 551 */ 552 public RobotCentric withVelocityX(double newVelocityX) { 553 this.VelocityX = newVelocityX; 554 return this; 555 } 556 557 /** 558 * Modifies the VelocityX parameter and returns itself. 559 * <p> 560 * The velocity in the X direction, in m/s. X is defined as forward according to 561 * WPILib convention, so this determines how fast to travel forward. 562 * 563 * @param newVelocityX Parameter to modify 564 * @return this object 565 */ 566 public RobotCentric withVelocityX(LinearVelocity newVelocityX) { 567 this.VelocityX = newVelocityX.in(MetersPerSecond); 568 return this; 569 } 570 571 /** 572 * Modifies the VelocityY parameter and returns itself. 573 * <p> 574 * The velocity in the Y direction, in m/s. Y is defined as to the left 575 * according to WPILib convention, so this determines how fast to travel to the 576 * left. 577 * 578 * @param newVelocityY Parameter to modify 579 * @return this object 580 */ 581 public RobotCentric withVelocityY(double newVelocityY) { 582 this.VelocityY = newVelocityY; 583 return this; 584 } 585 586 /** 587 * Modifies the VelocityY parameter and returns itself. 588 * <p> 589 * The velocity in the Y direction, in m/s. Y is defined as to the left 590 * according to WPILib convention, so this determines how fast to travel to the 591 * left. 592 * 593 * @param newVelocityY Parameter to modify 594 * @return this object 595 */ 596 public RobotCentric withVelocityY(LinearVelocity newVelocityY) { 597 this.VelocityY = newVelocityY.in(MetersPerSecond); 598 return this; 599 } 600 601 /** 602 * Modifies the RotationalRate parameter and returns itself. 603 * <p> 604 * The angular rate to rotate at, in radians per second. Angular rate is defined 605 * as counterclockwise positive, so this determines how fast to turn 606 * counterclockwise. 607 * 608 * @param newRotationalRate Parameter to modify 609 * @return this object 610 */ 611 public RobotCentric withRotationalRate(double newRotationalRate) { 612 this.RotationalRate = newRotationalRate; 613 return this; 614 } 615 616 /** 617 * Modifies the RotationalRate parameter and returns itself. 618 * <p> 619 * The angular rate to rotate at, in radians per second. Angular rate is defined 620 * as counterclockwise positive, so this determines how fast to turn 621 * counterclockwise. 622 * 623 * @param newRotationalRate Parameter to modify 624 * @return this object 625 */ 626 public RobotCentric withRotationalRate(AngularVelocity newRotationalRate) { 627 this.RotationalRate = newRotationalRate.in(RadiansPerSecond); 628 return this; 629 } 630 631 /** 632 * Modifies the Deadband parameter and returns itself. 633 * <p> 634 * The allowable deadband of the request, in m/s. 635 * 636 * @param newDeadband Parameter to modify 637 * @return this object 638 */ 639 public RobotCentric withDeadband(double newDeadband) { 640 this.Deadband = newDeadband; 641 return this; 642 } 643 644 /** 645 * Modifies the Deadband parameter and returns itself. 646 * <p> 647 * The allowable deadband of the request, in m/s. 648 * 649 * @param newDeadband Parameter to modify 650 * @return this object 651 */ 652 public RobotCentric withDeadband(LinearVelocity newDeadband) { 653 this.Deadband = newDeadband.in(MetersPerSecond); 654 return this; 655 } 656 657 /** 658 * Modifies the RotationalDeadband parameter and returns itself. 659 * <p> 660 * The rotational deadband of the request, in radians per second. 661 * 662 * @param newRotationalDeadband Parameter to modify 663 * @return this object 664 */ 665 public RobotCentric withRotationalDeadband(double newRotationalDeadband) { 666 this.RotationalDeadband = newRotationalDeadband; 667 return this; 668 } 669 670 /** 671 * Modifies the RotationalDeadband parameter and returns itself. 672 * <p> 673 * The rotational deadband of the request, in radians per second. 674 * 675 * @param newRotationalDeadband Parameter to modify 676 * @return this object 677 */ 678 public RobotCentric withRotationalDeadband(AngularVelocity newRotationalDeadband) { 679 this.RotationalDeadband = newRotationalDeadband.in(RadiansPerSecond); 680 return this; 681 } 682 683 /** 684 * Modifies the CenterOfRotation parameter and returns itself. 685 * <p> 686 * The center of rotation the robot should rotate around. This is (0,0) by 687 * default, which will rotate around the center of the robot. 688 * 689 * @param newCenterOfRotation Parameter to modify 690 * @return this object 691 */ 692 public RobotCentric withCenterOfRotation(Translation2d newCenterOfRotation) { 693 this.CenterOfRotation = newCenterOfRotation; 694 return this; 695 } 696 697 /** 698 * Modifies the DriveRequestType parameter and returns itself. 699 * <p> 700 * The type of control request to use for the drive motor. 701 * 702 * @param newDriveRequestType Parameter to modify 703 * @return this object 704 */ 705 public RobotCentric withDriveRequestType(SwerveModule.DriveRequestType newDriveRequestType) { 706 this.DriveRequestType = newDriveRequestType; 707 return this; 708 } 709 710 /** 711 * Modifies the SteerRequestType parameter and returns itself. 712 * <p> 713 * The type of control request to use for the drive motor. 714 * 715 * @param newSteerRequestType Parameter to modify 716 * @return this object 717 */ 718 public RobotCentric withSteerRequestType(SwerveModule.SteerRequestType newSteerRequestType) { 719 this.SteerRequestType = newSteerRequestType; 720 return this; 721 } 722 723 /** 724 * Modifies the DesaturateWheelSpeeds parameter and returns itself. 725 * <p> 726 * Whether to desaturate wheel speeds before applying. For more information, see 727 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 728 * 729 * @param newDesaturateWheelSpeeds Parameter to modify 730 * @return this object 731 */ 732 public RobotCentric withDesaturateWheelSpeeds(boolean newDesaturateWheelSpeeds) { 733 this.DesaturateWheelSpeeds = newDesaturateWheelSpeeds; 734 return this; 735 } 736 737 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 738 return StatusCode.valueOf(SwerveJNI.JNI_Request_Apply_RobotCentric(parameters.drivetrainId, 739 VelocityX, 740 VelocityY, 741 RotationalRate, 742 Deadband, 743 RotationalDeadband, 744 CenterOfRotation.getX(), 745 CenterOfRotation.getY(), 746 DriveRequestType.value, 747 SteerRequestType.value, 748 DesaturateWheelSpeeds)); 749 } 750 751 public void applyNative(int id) { 752 SwerveJNI.JNI_SetControl_RobotCentric(id, 753 VelocityX, 754 VelocityY, 755 RotationalRate, 756 Deadband, 757 RotationalDeadband, 758 CenterOfRotation.getX(), 759 CenterOfRotation.getY(), 760 DriveRequestType.value, 761 SteerRequestType.value, 762 DesaturateWheelSpeeds); 763 } 764 } 765 766 /** 767 * Sets the swerve drive modules to point to a specified direction. 768 */ 769 public static class PointWheelsAt implements NativeSwerveRequest { 770 /** 771 * The direction to point the modules toward. This direction is still optimized 772 * to what the module was previously at. 773 */ 774 public Rotation2d ModuleDirection = new Rotation2d(); 775 /** 776 * The type of control request to use for the drive motor. 777 */ 778 public SwerveModule.DriveRequestType DriveRequestType = SwerveModule.DriveRequestType.OpenLoopVoltage; 779 /** 780 * The type of control request to use for the drive motor. 781 */ 782 public SwerveModule.SteerRequestType SteerRequestType = SwerveModule.SteerRequestType.Position; 783 784 /** 785 * Modifies the ModuleDirection parameter and returns itself. 786 * <p> 787 * The direction to point the modules toward. This direction is still optimized 788 * to what the module was previously at. 789 * 790 * @param newModuleDirection Parameter to modify 791 * @return this object 792 */ 793 public PointWheelsAt withModuleDirection(Rotation2d newModuleDirection) { 794 this.ModuleDirection = newModuleDirection; 795 return this; 796 } 797 798 /** 799 * Modifies the DriveRequestType parameter and returns itself. 800 * <p> 801 * The type of control request to use for the drive motor. 802 * 803 * @param newDriveRequestType Parameter to modify 804 * @return this object 805 */ 806 public PointWheelsAt withDriveRequestType(SwerveModule.DriveRequestType newDriveRequestType) { 807 this.DriveRequestType = newDriveRequestType; 808 return this; 809 } 810 811 /** 812 * Modifies the SteerRequestType parameter and returns itself. 813 * <p> 814 * The type of control request to use for the drive motor. 815 * 816 * @param newSteerRequestType Parameter to modify 817 * @return this object 818 */ 819 public PointWheelsAt withSteerRequestType(SwerveModule.SteerRequestType newSteerRequestType) { 820 this.SteerRequestType = newSteerRequestType; 821 return this; 822 } 823 824 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 825 return StatusCode.valueOf(SwerveJNI.JNI_Request_Apply_PointWheelsAt(parameters.drivetrainId, 826 ModuleDirection.getRadians(), 827 DriveRequestType.value, 828 SteerRequestType.value)); 829 } 830 831 public void applyNative(int id) { 832 SwerveJNI.JNI_SetControl_PointWheelsAt(id, 833 ModuleDirection.getRadians(), 834 DriveRequestType.value, 835 SteerRequestType.value); 836 } 837 } 838 839 /** 840 * Accepts a generic robot-centric ChassisSpeeds to apply to the drivetrain. 841 */ 842 public static class ApplyRobotSpeeds implements NativeSwerveRequest { 843 /** 844 * The robot-centric chassis speeds to apply to the drivetrain. 845 */ 846 public ChassisSpeeds Speeds = new ChassisSpeeds(); 847 /** 848 * Robot-centric wheel force feedforwards to apply in the X direction, in 849 * newtons. X is defined as forward according to WPILib convention, so this 850 * determines the forward forces to apply. 851 * <p> 852 * These forces should include friction applied to the ground. 853 * <p> 854 * The order of the forces should match the order of the modules returned from 855 * SwerveDrivetrain. 856 */ 857 public double[] WheelForceFeedforwardsX = {}; 858 /** 859 * Robot-centric wheel force feedforwards to apply in the Y direction, in 860 * newtons. Y is defined as to the left according to WPILib convention, so this 861 * determines the forces to apply to the left. 862 * <p> 863 * These forces should include friction applied to the ground. 864 * <p> 865 * The order of the forces should match the order of the modules returned from 866 * SwerveDrivetrain. 867 */ 868 public double[] WheelForceFeedforwardsY = {}; 869 /** 870 * The center of rotation the robot should rotate around. This is (0,0) by 871 * default, which will rotate around the center of the robot. 872 */ 873 public Translation2d CenterOfRotation = new Translation2d(); 874 /** 875 * The type of control request to use for the drive motor. 876 */ 877 public SwerveModule.DriveRequestType DriveRequestType = SwerveModule.DriveRequestType.OpenLoopVoltage; 878 /** 879 * The type of control request to use for the drive motor. 880 */ 881 public SwerveModule.SteerRequestType SteerRequestType = SwerveModule.SteerRequestType.Position; 882 /** 883 * Whether to desaturate wheel speeds before applying. For more information, see 884 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 885 */ 886 public boolean DesaturateWheelSpeeds = true; 887 888 /** 889 * Modifies the Speeds parameter and returns itself. 890 * <p> 891 * The robot-centric chassis speeds to apply to the drivetrain. 892 * 893 * @param newSpeeds Parameter to modify 894 * @return this object 895 */ 896 public ApplyRobotSpeeds withSpeeds(ChassisSpeeds newSpeeds) { 897 this.Speeds = newSpeeds; 898 return this; 899 } 900 901 /** 902 * Modifies the WheelForceFeedforwardsX parameter and returns itself. 903 * <p> 904 * Robot-centric wheel force feedforwards to apply in the X direction, in 905 * newtons. X is defined as forward according to WPILib convention, so this 906 * determines the forward forces to apply. 907 * <p> 908 * These forces should include friction applied to the ground. 909 * <p> 910 * The order of the forces should match the order of the modules returned from 911 * SwerveDrivetrain. 912 * 913 * @param newWheelForceFeedforwardsX Parameter to modify 914 * @return this object 915 */ 916 public ApplyRobotSpeeds withWheelForceFeedforwardsX(double[] newWheelForceFeedforwardsX) { 917 this.WheelForceFeedforwardsX = newWheelForceFeedforwardsX; 918 return this; 919 } 920 921 /** 922 * Modifies the WheelForceFeedforwardsX parameter and returns itself. 923 * <p> 924 * Robot-centric wheel force feedforwards to apply in the X direction, in 925 * newtons. X is defined as forward according to WPILib convention, so this 926 * determines the forward forces to apply. 927 * <p> 928 * These forces should include friction applied to the ground. 929 * <p> 930 * The order of the forces should match the order of the modules returned from 931 * SwerveDrivetrain. 932 * 933 * @param newWheelForceFeedforwardsX Parameter to modify 934 * @return this object 935 */ 936 public ApplyRobotSpeeds withWheelForceFeedforwardsX(Force[] newWheelForceFeedforwardsX) { 937 if (this.WheelForceFeedforwardsX.length != newWheelForceFeedforwardsX.length) { 938 this.WheelForceFeedforwardsX = new double[newWheelForceFeedforwardsX.length]; 939 } 940 for (int i = 0; i < this.WheelForceFeedforwardsX.length; ++i) { 941 this.WheelForceFeedforwardsX[i] = newWheelForceFeedforwardsX[i].in(Newtons); 942 } 943 944 return this; 945 } 946 947 /** 948 * Modifies the WheelForceFeedforwardsY parameter and returns itself. 949 * <p> 950 * Robot-centric wheel force feedforwards to apply in the Y direction, in 951 * newtons. Y is defined as to the left according to WPILib convention, so this 952 * determines the forces to apply to the left. 953 * <p> 954 * These forces should include friction applied to the ground. 955 * <p> 956 * The order of the forces should match the order of the modules returned from 957 * SwerveDrivetrain. 958 * 959 * @param newWheelForceFeedforwardsY Parameter to modify 960 * @return this object 961 */ 962 public ApplyRobotSpeeds withWheelForceFeedforwardsY(double[] newWheelForceFeedforwardsY) { 963 this.WheelForceFeedforwardsY = newWheelForceFeedforwardsY; 964 return this; 965 } 966 967 /** 968 * Modifies the WheelForceFeedforwardsY parameter and returns itself. 969 * <p> 970 * Robot-centric wheel force feedforwards to apply in the Y direction, in 971 * newtons. Y is defined as to the left according to WPILib convention, so this 972 * determines the forces to apply to the left. 973 * <p> 974 * These forces should include friction applied to the ground. 975 * <p> 976 * The order of the forces should match the order of the modules returned from 977 * SwerveDrivetrain. 978 * 979 * @param newWheelForceFeedforwardsY Parameter to modify 980 * @return this object 981 */ 982 public ApplyRobotSpeeds withWheelForceFeedforwardsY(Force[] newWheelForceFeedforwardsY) { 983 if (this.WheelForceFeedforwardsY.length != newWheelForceFeedforwardsY.length) { 984 this.WheelForceFeedforwardsY = new double[newWheelForceFeedforwardsY.length]; 985 } 986 for (int i = 0; i < this.WheelForceFeedforwardsY.length; ++i) { 987 this.WheelForceFeedforwardsY[i] = newWheelForceFeedforwardsY[i].in(Newtons); 988 } 989 990 return this; 991 } 992 993 /** 994 * Modifies the CenterOfRotation parameter and returns itself. 995 * <p> 996 * The center of rotation the robot should rotate around. This is (0,0) by 997 * default, which will rotate around the center of the robot. 998 * 999 * @param newCenterOfRotation Parameter to modify 1000 * @return this object 1001 */ 1002 public ApplyRobotSpeeds withCenterOfRotation(Translation2d newCenterOfRotation) { 1003 this.CenterOfRotation = newCenterOfRotation; 1004 return this; 1005 } 1006 1007 /** 1008 * Modifies the DriveRequestType parameter and returns itself. 1009 * <p> 1010 * The type of control request to use for the drive motor. 1011 * 1012 * @param newDriveRequestType Parameter to modify 1013 * @return this object 1014 */ 1015 public ApplyRobotSpeeds withDriveRequestType(SwerveModule.DriveRequestType newDriveRequestType) { 1016 this.DriveRequestType = newDriveRequestType; 1017 return this; 1018 } 1019 1020 /** 1021 * Modifies the SteerRequestType parameter and returns itself. 1022 * <p> 1023 * The type of control request to use for the drive motor. 1024 * 1025 * @param newSteerRequestType Parameter to modify 1026 * @return this object 1027 */ 1028 public ApplyRobotSpeeds withSteerRequestType(SwerveModule.SteerRequestType newSteerRequestType) { 1029 this.SteerRequestType = newSteerRequestType; 1030 return this; 1031 } 1032 1033 /** 1034 * Modifies the DesaturateWheelSpeeds parameter and returns itself. 1035 * <p> 1036 * Whether to desaturate wheel speeds before applying. For more information, see 1037 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 1038 * 1039 * @param newDesaturateWheelSpeeds Parameter to modify 1040 * @return this object 1041 */ 1042 public ApplyRobotSpeeds withDesaturateWheelSpeeds(boolean newDesaturateWheelSpeeds) { 1043 this.DesaturateWheelSpeeds = newDesaturateWheelSpeeds; 1044 return this; 1045 } 1046 1047 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 1048 return StatusCode.valueOf(SwerveJNI.JNI_Request_Apply_ApplyRobotSpeeds(parameters.drivetrainId, 1049 Speeds.vxMetersPerSecond, 1050 Speeds.vyMetersPerSecond, 1051 Speeds.omegaRadiansPerSecond, 1052 WheelForceFeedforwardsX, 1053 WheelForceFeedforwardsY, 1054 CenterOfRotation.getX(), 1055 CenterOfRotation.getY(), 1056 DriveRequestType.value, 1057 SteerRequestType.value, 1058 DesaturateWheelSpeeds)); 1059 } 1060 1061 public void applyNative(int id) { 1062 SwerveJNI.JNI_SetControl_ApplyRobotSpeeds(id, 1063 Speeds.vxMetersPerSecond, 1064 Speeds.vyMetersPerSecond, 1065 Speeds.omegaRadiansPerSecond, 1066 WheelForceFeedforwardsX, 1067 WheelForceFeedforwardsY, 1068 CenterOfRotation.getX(), 1069 CenterOfRotation.getY(), 1070 DriveRequestType.value, 1071 SteerRequestType.value, 1072 DesaturateWheelSpeeds); 1073 } 1074 } 1075 1076 /** 1077 * Accepts a generic robot-centric ChassisSpeeds to apply to the drivetrain. 1078 * 1079 * @deprecated Use {@link ApplyRobotSpeeds} instead 1080 */ 1081 @Deprecated(forRemoval = true, since = "2025") 1082 public static class ApplyChassisSpeeds extends ApplyRobotSpeeds {} 1083 1084 /** 1085 * Accepts a generic field-centric ChassisSpeeds to apply to the drivetrain. 1086 */ 1087 public static class ApplyFieldSpeeds implements NativeSwerveRequest { 1088 /** 1089 * The field-centric chassis speeds to apply to the drivetrain. 1090 */ 1091 public ChassisSpeeds Speeds = new ChassisSpeeds(); 1092 /** 1093 * Field-centric wheel force feedforwards to apply in the X direction, in 1094 * newtons. X is defined as forward according to WPILib convention, so this 1095 * determines the forward forces to apply. 1096 * <p> 1097 * These forces should include friction applied to the ground. 1098 * <p> 1099 * The order of the forces should match the order of the modules returned from 1100 * SwerveDrivetrain. 1101 */ 1102 public double[] WheelForceFeedforwardsX = {}; 1103 /** 1104 * Field-centric wheel force feedforwards to apply in the Y direction, in 1105 * newtons. Y is defined as to the left according to WPILib convention, so this 1106 * determines the forces to apply to the left. 1107 * <p> 1108 * These forces should include friction applied to the ground. 1109 * <p> 1110 * The order of the forces should match the order of the modules returned from 1111 * SwerveDrivetrain. 1112 */ 1113 public double[] WheelForceFeedforwardsY = {}; 1114 /** 1115 * The center of rotation the robot should rotate around. This is (0,0) by 1116 * default, which will rotate around the center of the robot. 1117 */ 1118 public Translation2d CenterOfRotation = new Translation2d(); 1119 /** 1120 * The type of control request to use for the drive motor. 1121 */ 1122 public SwerveModule.DriveRequestType DriveRequestType = SwerveModule.DriveRequestType.OpenLoopVoltage; 1123 /** 1124 * The type of control request to use for the drive motor. 1125 */ 1126 public SwerveModule.SteerRequestType SteerRequestType = SwerveModule.SteerRequestType.Position; 1127 /** 1128 * Whether to desaturate wheel speeds before applying. For more information, see 1129 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 1130 */ 1131 public boolean DesaturateWheelSpeeds = true; 1132 /** 1133 * The perspective to use when determining which direction is forward. 1134 */ 1135 public ForwardPerspectiveValue ForwardPerspective = ForwardPerspectiveValue.BlueAlliance; 1136 1137 /** 1138 * Modifies the Speeds parameter and returns itself. 1139 * <p> 1140 * The field-centric chassis speeds to apply to the drivetrain. 1141 * 1142 * @param newSpeeds Parameter to modify 1143 * @return this object 1144 */ 1145 public ApplyFieldSpeeds withSpeeds(ChassisSpeeds newSpeeds) { 1146 this.Speeds = newSpeeds; 1147 return this; 1148 } 1149 1150 /** 1151 * Modifies the WheelForceFeedforwardsX parameter and returns itself. 1152 * <p> 1153 * Field-centric wheel force feedforwards to apply in the X direction, in 1154 * newtons. X is defined as forward according to WPILib convention, so this 1155 * determines the forward forces to apply. 1156 * <p> 1157 * These forces should include friction applied to the ground. 1158 * <p> 1159 * The order of the forces should match the order of the modules returned from 1160 * SwerveDrivetrain. 1161 * 1162 * @param newWheelForceFeedforwardsX Parameter to modify 1163 * @return this object 1164 */ 1165 public ApplyFieldSpeeds withWheelForceFeedforwardsX(double[] newWheelForceFeedforwardsX) { 1166 this.WheelForceFeedforwardsX = newWheelForceFeedforwardsX; 1167 return this; 1168 } 1169 1170 /** 1171 * Modifies the WheelForceFeedforwardsX parameter and returns itself. 1172 * <p> 1173 * Field-centric wheel force feedforwards to apply in the X direction, in 1174 * newtons. X is defined as forward according to WPILib convention, so this 1175 * determines the forward forces to apply. 1176 * <p> 1177 * These forces should include friction applied to the ground. 1178 * <p> 1179 * The order of the forces should match the order of the modules returned from 1180 * SwerveDrivetrain. 1181 * 1182 * @param newWheelForceFeedforwardsX Parameter to modify 1183 * @return this object 1184 */ 1185 public ApplyFieldSpeeds withWheelForceFeedforwardsX(Force[] newWheelForceFeedforwardsX) { 1186 if (this.WheelForceFeedforwardsX.length != newWheelForceFeedforwardsX.length) { 1187 this.WheelForceFeedforwardsX = new double[newWheelForceFeedforwardsX.length]; 1188 } 1189 for (int i = 0; i < this.WheelForceFeedforwardsX.length; ++i) { 1190 this.WheelForceFeedforwardsX[i] = newWheelForceFeedforwardsX[i].in(Newtons); 1191 } 1192 1193 return this; 1194 } 1195 1196 /** 1197 * Modifies the WheelForceFeedforwardsY parameter and returns itself. 1198 * <p> 1199 * Field-centric wheel force feedforwards to apply in the Y direction, in 1200 * newtons. Y is defined as to the left according to WPILib convention, so this 1201 * determines the forces to apply to the left. 1202 * <p> 1203 * These forces should include friction applied to the ground. 1204 * <p> 1205 * The order of the forces should match the order of the modules returned from 1206 * SwerveDrivetrain. 1207 * 1208 * @param newWheelForceFeedforwardsY Parameter to modify 1209 * @return this object 1210 */ 1211 public ApplyFieldSpeeds withWheelForceFeedforwardsY(double[] newWheelForceFeedforwardsY) { 1212 this.WheelForceFeedforwardsY = newWheelForceFeedforwardsY; 1213 return this; 1214 } 1215 1216 /** 1217 * Modifies the WheelForceFeedforwardsY parameter and returns itself. 1218 * <p> 1219 * Field-centric wheel force feedforwards to apply in the Y direction, in 1220 * newtons. Y is defined as to the left according to WPILib convention, so this 1221 * determines the forces to apply to the left. 1222 * <p> 1223 * These forces should include friction applied to the ground. 1224 * <p> 1225 * The order of the forces should match the order of the modules returned from 1226 * SwerveDrivetrain. 1227 * 1228 * @param newWheelForceFeedforwardsY Parameter to modify 1229 * @return this object 1230 */ 1231 public ApplyFieldSpeeds withWheelForceFeedforwardsY(Force[] newWheelForceFeedforwardsY) { 1232 if (this.WheelForceFeedforwardsY.length != newWheelForceFeedforwardsY.length) { 1233 this.WheelForceFeedforwardsY = new double[newWheelForceFeedforwardsY.length]; 1234 } 1235 for (int i = 0; i < this.WheelForceFeedforwardsY.length; ++i) { 1236 this.WheelForceFeedforwardsY[i] = newWheelForceFeedforwardsY[i].in(Newtons); 1237 } 1238 1239 return this; 1240 } 1241 1242 /** 1243 * Modifies the CenterOfRotation parameter and returns itself. 1244 * <p> 1245 * The center of rotation the robot should rotate around. This is (0,0) by 1246 * default, which will rotate around the center of the robot. 1247 * 1248 * @param newCenterOfRotation Parameter to modify 1249 * @return this object 1250 */ 1251 public ApplyFieldSpeeds withCenterOfRotation(Translation2d newCenterOfRotation) { 1252 this.CenterOfRotation = newCenterOfRotation; 1253 return this; 1254 } 1255 1256 /** 1257 * Modifies the DriveRequestType parameter and returns itself. 1258 * <p> 1259 * The type of control request to use for the drive motor. 1260 * 1261 * @param newDriveRequestType Parameter to modify 1262 * @return this object 1263 */ 1264 public ApplyFieldSpeeds withDriveRequestType(SwerveModule.DriveRequestType newDriveRequestType) { 1265 this.DriveRequestType = newDriveRequestType; 1266 return this; 1267 } 1268 1269 /** 1270 * Modifies the SteerRequestType parameter and returns itself. 1271 * <p> 1272 * The type of control request to use for the drive motor. 1273 * 1274 * @param newSteerRequestType Parameter to modify 1275 * @return this object 1276 */ 1277 public ApplyFieldSpeeds withSteerRequestType(SwerveModule.SteerRequestType newSteerRequestType) { 1278 this.SteerRequestType = newSteerRequestType; 1279 return this; 1280 } 1281 1282 /** 1283 * Modifies the DesaturateWheelSpeeds parameter and returns itself. 1284 * <p> 1285 * Whether to desaturate wheel speeds before applying. For more information, see 1286 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 1287 * 1288 * @param newDesaturateWheelSpeeds Parameter to modify 1289 * @return this object 1290 */ 1291 public ApplyFieldSpeeds withDesaturateWheelSpeeds(boolean newDesaturateWheelSpeeds) { 1292 this.DesaturateWheelSpeeds = newDesaturateWheelSpeeds; 1293 return this; 1294 } 1295 1296 /** 1297 * Modifies the ForwardPerspective parameter and returns itself. 1298 * <p> 1299 * The perspective to use when determining which direction is forward. 1300 * 1301 * @param newForwardPerspective Parameter to modify 1302 * @return this object 1303 */ 1304 public ApplyFieldSpeeds withForwardPerspective(ForwardPerspectiveValue newForwardPerspective) { 1305 this.ForwardPerspective = newForwardPerspective; 1306 return this; 1307 } 1308 1309 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 1310 return StatusCode.valueOf(SwerveJNI.JNI_Request_Apply_ApplyFieldSpeeds(parameters.drivetrainId, 1311 Speeds.vxMetersPerSecond, 1312 Speeds.vyMetersPerSecond, 1313 Speeds.omegaRadiansPerSecond, 1314 WheelForceFeedforwardsX, 1315 WheelForceFeedforwardsY, 1316 CenterOfRotation.getX(), 1317 CenterOfRotation.getY(), 1318 DriveRequestType.value, 1319 SteerRequestType.value, 1320 DesaturateWheelSpeeds, 1321 ForwardPerspective.value)); 1322 } 1323 1324 public void applyNative(int id) { 1325 SwerveJNI.JNI_SetControl_ApplyFieldSpeeds(id, 1326 Speeds.vxMetersPerSecond, 1327 Speeds.vyMetersPerSecond, 1328 Speeds.omegaRadiansPerSecond, 1329 WheelForceFeedforwardsX, 1330 WheelForceFeedforwardsY, 1331 CenterOfRotation.getX(), 1332 CenterOfRotation.getY(), 1333 DriveRequestType.value, 1334 SteerRequestType.value, 1335 DesaturateWheelSpeeds, 1336 ForwardPerspective.value); 1337 } 1338 } 1339 1340 /** 1341 * Drives the swerve drivetrain in a field-centric manner, maintaining a 1342 * specified heading angle to ensure the robot is facing the desired direction 1343 * <p> 1344 * When users use this request, they specify the direction the robot should 1345 * travel oriented against the field, and the direction the robot should be facing. 1346 * <p> 1347 * An example scenario is that the robot is oriented to the east, the VelocityX 1348 * is +5 m/s, VelocityY is 0 m/s, and TargetDirection is 180 degrees. 1349 * In this scenario, the robot would drive northward at 5 m/s and turn clockwise 1350 * to a target of 180 degrees. 1351 * <p> 1352 * This control request is especially useful for autonomous control, where the 1353 * robot should be facing a changing direction throughout the motion. 1354 */ 1355 public static class FieldCentricFacingAngle implements SwerveRequest { 1356 /** 1357 * The velocity in the X direction, in m/s. 1358 * X is defined as forward according to WPILib convention, 1359 * so this determines how fast to travel forward. 1360 */ 1361 public double VelocityX = 0; 1362 /** 1363 * The velocity in the Y direction, in m/s. 1364 * Y is defined as to the left according to WPILib convention, 1365 * so this determines how fast to travel to the left. 1366 */ 1367 public double VelocityY = 0; 1368 /** 1369 * The desired direction to face. 1370 * 0 Degrees is defined as in the direction of the X axis. 1371 * As a result, a TargetDirection of 90 degrees will point along 1372 * the Y axis, or to the left. 1373 */ 1374 public Rotation2d TargetDirection = new Rotation2d(); 1375 /** 1376 * The rotational rate feedforward to add to the output of the heading 1377 * controller, in radians per second. When using a motion profile for the 1378 * target direction, this can be set to the current velocity reference of 1379 * the profile. 1380 */ 1381 public double TargetRateFeedforward = 0; 1382 1383 /** 1384 * The allowable deadband of the request, in m/s. 1385 */ 1386 public double Deadband = 0; 1387 /** 1388 * The rotational deadband of the request, in radians per second. 1389 */ 1390 public double RotationalDeadband = 0; 1391 /** 1392 * The maximum absolute rotational rate to allow, in radians per second. 1393 * Setting this to 0 results in no cap to rotational rate. 1394 */ 1395 public double MaxAbsRotationalRate = 0; 1396 /** 1397 * The center of rotation the robot should rotate around. 1398 * This is (0,0) by default, which will rotate around the center of the robot. 1399 */ 1400 public Translation2d CenterOfRotation = new Translation2d(); 1401 1402 /** 1403 * The type of control request to use for the drive motor. 1404 */ 1405 public SwerveModule.DriveRequestType DriveRequestType = SwerveModule.DriveRequestType.OpenLoopVoltage; 1406 /** 1407 * The type of control request to use for the steer motor. 1408 */ 1409 public SwerveModule.SteerRequestType SteerRequestType = SwerveModule.SteerRequestType.Position; 1410 /** 1411 * Whether to desaturate wheel speeds before applying. 1412 * For more information, see the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 1413 */ 1414 public boolean DesaturateWheelSpeeds = true; 1415 1416 /** 1417 * The perspective to use when determining which direction is forward. 1418 */ 1419 public ForwardPerspectiveValue ForwardPerspective = ForwardPerspectiveValue.OperatorPerspective; 1420 1421 /** 1422 * The PID controller used to maintain the desired heading. 1423 * Users can specify the PID gains to change how aggressively to maintain 1424 * heading. 1425 * <p> 1426 * This PID controller operates on heading radians and outputs a target 1427 * rotational rate in radians per second. Note that continuous input should 1428 * be enabled on the range [-pi, pi]. 1429 */ 1430 public PhoenixPIDController HeadingController = new PhoenixPIDController(0, 0, 0); 1431 1432 private final FieldCentric m_fieldCentric = new FieldCentric(); 1433 1434 public FieldCentricFacingAngle() { 1435 HeadingController.enableContinuousInput(-Math.PI, Math.PI); 1436 } 1437 1438 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 1439 Rotation2d angleToFace = TargetDirection; 1440 if (ForwardPerspective == ForwardPerspectiveValue.OperatorPerspective) { 1441 /* If we're operator perspective, rotate the direction we want to face by the angle */ 1442 angleToFace = angleToFace.rotateBy(parameters.operatorForwardDirection); 1443 } 1444 1445 double toApplyOmega = TargetRateFeedforward + 1446 HeadingController.calculate( 1447 parameters.currentPose.getRotation().getRadians(), 1448 angleToFace.getRadians(), 1449 parameters.timestamp 1450 ); 1451 if (MaxAbsRotationalRate > 0.0) { 1452 if (toApplyOmega > MaxAbsRotationalRate) { 1453 toApplyOmega = MaxAbsRotationalRate; 1454 } else if (toApplyOmega < -MaxAbsRotationalRate) { 1455 toApplyOmega = -MaxAbsRotationalRate; 1456 } 1457 } 1458 1459 return m_fieldCentric 1460 .withVelocityX(VelocityX) 1461 .withVelocityY(VelocityY) 1462 .withRotationalRate(toApplyOmega) 1463 .withDeadband(Deadband) 1464 .withRotationalDeadband(RotationalDeadband) 1465 .withCenterOfRotation(CenterOfRotation) 1466 .withDriveRequestType(DriveRequestType) 1467 .withSteerRequestType(SteerRequestType) 1468 .withDesaturateWheelSpeeds(DesaturateWheelSpeeds) 1469 .withForwardPerspective(ForwardPerspective) 1470 .apply(parameters, modulesToApply); 1471 } 1472 1473 /** 1474 * Modifies the PID gains of the HeadingController parameter and returns itself. 1475 * <p> 1476 * Sets the proportional, integral, and differential coefficients used to maintain 1477 * the desired heading. Users can specify the PID gains to change how aggressively to 1478 * maintain heading. 1479 * <p> 1480 * This PID controller operates on heading radians and outputs a target 1481 * rotational rate in radians per second. 1482 * 1483 * @param kP The proportional coefficient; must be >= 0 1484 * @param kI The integral coefficient; must be >= 0 1485 * @param kD The differential coefficient; must be >= 0 1486 * @return this object 1487 */ 1488 public FieldCentricFacingAngle withHeadingPID(double kP, double kI, double kD) 1489 { 1490 this.HeadingController.setPID(kP, kI, kD); 1491 return this; 1492 } 1493 1494 /** 1495 * Modifies the VelocityX parameter and returns itself. 1496 * <p> 1497 * The velocity in the X direction, in m/s. X is defined as forward according to 1498 * WPILib convention, so this determines how fast to travel forward. 1499 * 1500 * @param newVelocityX Parameter to modify 1501 * @return this object 1502 */ 1503 public FieldCentricFacingAngle withVelocityX(double newVelocityX) { 1504 this.VelocityX = newVelocityX; 1505 return this; 1506 } 1507 1508 /** 1509 * Modifies the VelocityX parameter and returns itself. 1510 * <p> 1511 * The velocity in the X direction, in m/s. X is defined as forward according to 1512 * WPILib convention, so this determines how fast to travel forward. 1513 * 1514 * @param newVelocityX Parameter to modify 1515 * @return this object 1516 */ 1517 public FieldCentricFacingAngle withVelocityX(LinearVelocity newVelocityX) { 1518 this.VelocityX = newVelocityX.in(MetersPerSecond); 1519 return this; 1520 } 1521 1522 /** 1523 * Modifies the VelocityY parameter and returns itself. 1524 * <p> 1525 * The velocity in the Y direction, in m/s. Y is defined as to the left 1526 * according to WPILib convention, so this determines how fast to travel to the 1527 * left. 1528 * 1529 * @param newVelocityY Parameter to modify 1530 * @return this object 1531 */ 1532 public FieldCentricFacingAngle withVelocityY(double newVelocityY) { 1533 this.VelocityY = newVelocityY; 1534 return this; 1535 } 1536 1537 /** 1538 * Modifies the VelocityY parameter and returns itself. 1539 * <p> 1540 * The velocity in the Y direction, in m/s. Y is defined as to the left 1541 * according to WPILib convention, so this determines how fast to travel to the 1542 * left. 1543 * 1544 * @param newVelocityY Parameter to modify 1545 * @return this object 1546 */ 1547 public FieldCentricFacingAngle withVelocityY(LinearVelocity newVelocityY) { 1548 this.VelocityY = newVelocityY.in(MetersPerSecond); 1549 return this; 1550 } 1551 1552 /** 1553 * Modifies the TargetDirection parameter and returns itself. 1554 * <p> 1555 * The desired direction to face. 0 Degrees is defined as in the direction of 1556 * the X axis. As a result, a TargetDirection of 90 degrees will point along 1557 * the Y axis, or to the left. 1558 * 1559 * @param newTargetDirection Parameter to modify 1560 * @return this object 1561 */ 1562 public FieldCentricFacingAngle withTargetDirection(Rotation2d newTargetDirection) { 1563 this.TargetDirection = newTargetDirection; 1564 return this; 1565 } 1566 1567 /** 1568 * Modifies the TargetRateFeedforward parameter and returns itself. 1569 * <p> 1570 * The rotational rate feedforward to add to the output of the heading 1571 * controller, in radians per second. When using a motion profile for the 1572 * target direction, this can be set to the current velocity reference of 1573 * the profile. 1574 * 1575 * @param newTargetRateFeedforward Parameter to modify 1576 * @return this object 1577 */ 1578 public FieldCentricFacingAngle withTargetRateFeedforward(double newTargetRateFeedforward) { 1579 this.TargetRateFeedforward = newTargetRateFeedforward; 1580 return this; 1581 } 1582 /** 1583 * Modifies the TargetRateFeedforward parameter and returns itself. 1584 * <p> 1585 * The rotational rate feedforward to add to the output of the heading 1586 * controller, in radians per second. When using a motion profile for the 1587 * target direction, this can be set to the current velocity reference of 1588 * the profile. 1589 * 1590 * @param newTargetRateFeedforward Parameter to modify 1591 * @return this object 1592 */ 1593 public FieldCentricFacingAngle withTargetRateFeedforward(AngularVelocity newTargetRateFeedforward) { 1594 this.TargetRateFeedforward = newTargetRateFeedforward.in(RadiansPerSecond); 1595 return this; 1596 } 1597 1598 /** 1599 * Modifies the Deadband parameter and returns itself. 1600 * <p> 1601 * The allowable deadband of the request, in m/s. 1602 * 1603 * @param newDeadband Parameter to modify 1604 * @return this object 1605 */ 1606 public FieldCentricFacingAngle withDeadband(double newDeadband) { 1607 this.Deadband = newDeadband; 1608 return this; 1609 } 1610 1611 /** 1612 * Modifies the Deadband parameter and returns itself. 1613 * <p> 1614 * The allowable deadband of the request, in m/s. 1615 * 1616 * @param newDeadband Parameter to modify 1617 * @return this object 1618 */ 1619 public FieldCentricFacingAngle withDeadband(LinearVelocity newDeadband) { 1620 this.Deadband = newDeadband.in(MetersPerSecond); 1621 return this; 1622 } 1623 1624 /** 1625 * Modifies the RotationalDeadband parameter and returns itself. 1626 * <p> 1627 * The rotational deadband of the request, in radians per second. 1628 * 1629 * @param newRotationalDeadband Parameter to modify 1630 * @return this object 1631 */ 1632 public FieldCentricFacingAngle withRotationalDeadband(double newRotationalDeadband) { 1633 this.RotationalDeadband = newRotationalDeadband; 1634 return this; 1635 } 1636 1637 /** 1638 * Modifies the RotationalDeadband parameter and returns itself. 1639 * <p> 1640 * The rotational deadband of the request, in radians per second. 1641 * 1642 * @param newRotationalDeadband Parameter to modify 1643 * @return this object 1644 */ 1645 public FieldCentricFacingAngle withRotationalDeadband(AngularVelocity newRotationalDeadband) { 1646 this.RotationalDeadband = newRotationalDeadband.in(RadiansPerSecond); 1647 return this; 1648 } 1649 1650 /** 1651 * Modifies the MaxAbsRotationalRate parameter and returns itself. 1652 * <p> 1653 * The maximum absolute rotational rate to allow, in radians per second. 1654 * Setting this to 0 results in no cap to rotational rate. 1655 * 1656 * @param newMaxAbsRotationalRate Parameter to modify 1657 * @return this object 1658 */ 1659 public FieldCentricFacingAngle withMaxAbsRotationalRate(double newMaxAbsRotationalRate) { 1660 this.MaxAbsRotationalRate = newMaxAbsRotationalRate; 1661 return this; 1662 } 1663 1664 /** 1665 * Modifies the MaxAbsRotationalRate parameter and returns itself. 1666 * <p> 1667 * The maximum absolute rotational rate to allow, in radians per second. 1668 * Setting this to 0 results in no cap to rotational rate. 1669 * 1670 * @param newMaxAbsRotationalRate Parameter to modify 1671 * @return this object 1672 */ 1673 public FieldCentricFacingAngle withMaxAbsRotationalRate(AngularVelocity newMaxAbsRotationalRate) { 1674 this.MaxAbsRotationalRate = newMaxAbsRotationalRate.in(RadiansPerSecond); 1675 return this; 1676 } 1677 1678 /** 1679 * Modifies the CenterOfRotation parameter and returns itself. 1680 * <p> 1681 * The center of rotation the robot should rotate around. This is (0,0) by 1682 * default, which will rotate around the center of the robot. 1683 * 1684 * @param newCenterOfRotation Parameter to modify 1685 * @return this object 1686 */ 1687 public FieldCentricFacingAngle withCenterOfRotation(Translation2d newCenterOfRotation) { 1688 this.CenterOfRotation = newCenterOfRotation; 1689 return this; 1690 } 1691 1692 /** 1693 * Modifies the DriveRequestType parameter and returns itself. 1694 * <p> 1695 * The type of control request to use for the drive motor. 1696 * 1697 * @param newDriveRequestType Parameter to modify 1698 * @return this object 1699 */ 1700 public FieldCentricFacingAngle withDriveRequestType(SwerveModule.DriveRequestType newDriveRequestType) { 1701 this.DriveRequestType = newDriveRequestType; 1702 return this; 1703 } 1704 1705 /** 1706 * Modifies the SteerRequestType parameter and returns itself. 1707 * <p> 1708 * The type of control request to use for the drive motor. 1709 * 1710 * @param newSteerRequestType Parameter to modify 1711 * @return this object 1712 */ 1713 public FieldCentricFacingAngle withSteerRequestType(SwerveModule.SteerRequestType newSteerRequestType) { 1714 this.SteerRequestType = newSteerRequestType; 1715 return this; 1716 } 1717 1718 /** 1719 * Modifies the DesaturateWheelSpeeds parameter and returns itself. 1720 * <p> 1721 * Whether to desaturate wheel speeds before applying. For more information, see 1722 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 1723 * 1724 * @param newDesaturateWheelSpeeds Parameter to modify 1725 * @return this object 1726 */ 1727 public FieldCentricFacingAngle withDesaturateWheelSpeeds(boolean newDesaturateWheelSpeeds) { 1728 this.DesaturateWheelSpeeds = newDesaturateWheelSpeeds; 1729 return this; 1730 } 1731 1732 /** 1733 * Modifies the ForwardPerspective parameter and returns itself. 1734 * <p> 1735 * The perspective to use when determining which direction is forward. 1736 * 1737 * @param newForwardPerspective Parameter to modify 1738 * @return this object 1739 */ 1740 public FieldCentricFacingAngle withForwardPerspective(ForwardPerspectiveValue newForwardPerspective) { 1741 this.ForwardPerspective = newForwardPerspective; 1742 return this; 1743 } 1744 } 1745 1746 /** 1747 * Drives the swerve drivetrain in a robot-centric manner, maintaining a 1748 * specified heading angle to ensure the robot is facing the desired direction 1749 * <p> 1750 * When users use this request, they specify the direction the robot should 1751 * travel oriented against the robot itself, and the direction the robot should 1752 * be facing relative to the field. 1753 * <p> 1754 * An example scenario is that the robot is oriented to the east, the VelocityX 1755 * is +5 m/s, VelocityY is 0 m/s, and TargetDirection is 180 degrees. 1756 * In this scenario, the robot would drive forward at 5 m/s and turn clockwise 1757 * to a target of 180 degrees. 1758 * <p> 1759 * This control request is especially useful for vision control, where the 1760 * robot should be facing a vision target throughout the motion. 1761 */ 1762 public static class RobotCentricFacingAngle implements SwerveRequest { 1763 /** 1764 * The velocity in the X direction, in m/s. 1765 * X is defined as forward according to WPILib convention, 1766 * so this determines how fast to travel forward. 1767 */ 1768 public double VelocityX = 0; 1769 /** 1770 * The velocity in the Y direction, in m/s. 1771 * Y is defined as to the left according to WPILib convention, 1772 * so this determines how fast to travel to the left. 1773 */ 1774 public double VelocityY = 0; 1775 /** 1776 * The desired direction to face. 1777 * 0 Degrees is defined as in the direction of the X axis. 1778 * As a result, a TargetDirection of 90 degrees will point along 1779 * the Y axis, or to the left. 1780 */ 1781 public Rotation2d TargetDirection = new Rotation2d(); 1782 /** 1783 * The rotational rate feedforward to add to the output of the heading 1784 * controller, in radians per second. When using a motion profile for the 1785 * target direction, this can be set to the current velocity reference of 1786 * the profile. 1787 */ 1788 public double TargetRateFeedforward = 0; 1789 1790 /** 1791 * The allowable deadband of the request, in m/s. 1792 */ 1793 public double Deadband = 0; 1794 /** 1795 * The rotational deadband of the request, in radians per second. 1796 */ 1797 public double RotationalDeadband = 0; 1798 /** 1799 * The maximum absolute rotational rate to allow, in radians per second. 1800 * Setting this to 0 results in no cap to rotational rate. 1801 */ 1802 public double MaxAbsRotationalRate = 0; 1803 /** 1804 * The center of rotation the robot should rotate around. 1805 * This is (0,0) by default, which will rotate around the center of the robot. 1806 */ 1807 public Translation2d CenterOfRotation = new Translation2d(); 1808 1809 /** 1810 * The type of control request to use for the drive motor. 1811 */ 1812 public SwerveModule.DriveRequestType DriveRequestType = SwerveModule.DriveRequestType.OpenLoopVoltage; 1813 /** 1814 * The type of control request to use for the steer motor. 1815 */ 1816 public SwerveModule.SteerRequestType SteerRequestType = SwerveModule.SteerRequestType.Position; 1817 /** 1818 * Whether to desaturate wheel speeds before applying. 1819 * For more information, see the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 1820 */ 1821 public boolean DesaturateWheelSpeeds = true; 1822 1823 /** 1824 * The perspective to use when determining which direction is forward 1825 * for the target heading. 1826 */ 1827 public ForwardPerspectiveValue ForwardPerspective = ForwardPerspectiveValue.OperatorPerspective; 1828 1829 /** 1830 * The PID controller used to maintain the desired heading. 1831 * Users can specify the PID gains to change how aggressively to maintain 1832 * heading. 1833 * <p> 1834 * This PID controller operates on heading radians and outputs a target 1835 * rotational rate in radians per second. Note that continuous input should 1836 * be enabled on the range [-pi, pi]. 1837 */ 1838 public PhoenixPIDController HeadingController = new PhoenixPIDController(0, 0, 0); 1839 1840 private final RobotCentric m_robotCentric = new RobotCentric(); 1841 1842 public RobotCentricFacingAngle() { 1843 HeadingController.enableContinuousInput(-Math.PI, Math.PI); 1844 } 1845 1846 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 1847 Rotation2d angleToFace = TargetDirection; 1848 if (ForwardPerspective == ForwardPerspectiveValue.OperatorPerspective) { 1849 /* If we're operator perspective, rotate the direction we want to face by the angle */ 1850 angleToFace = angleToFace.rotateBy(parameters.operatorForwardDirection); 1851 } 1852 1853 double toApplyOmega = TargetRateFeedforward + 1854 HeadingController.calculate( 1855 parameters.currentPose.getRotation().getRadians(), 1856 angleToFace.getRadians(), 1857 parameters.timestamp 1858 ); 1859 if (MaxAbsRotationalRate > 0.0) { 1860 if (toApplyOmega > MaxAbsRotationalRate) { 1861 toApplyOmega = MaxAbsRotationalRate; 1862 } else if (toApplyOmega < -MaxAbsRotationalRate) { 1863 toApplyOmega = -MaxAbsRotationalRate; 1864 } 1865 } 1866 1867 return m_robotCentric 1868 .withVelocityX(VelocityX) 1869 .withVelocityY(VelocityY) 1870 .withRotationalRate(toApplyOmega) 1871 .withDeadband(Deadband) 1872 .withRotationalDeadband(RotationalDeadband) 1873 .withCenterOfRotation(CenterOfRotation) 1874 .withDriveRequestType(DriveRequestType) 1875 .withSteerRequestType(SteerRequestType) 1876 .withDesaturateWheelSpeeds(DesaturateWheelSpeeds) 1877 .apply(parameters, modulesToApply); 1878 } 1879 1880 /** 1881 * Modifies the PID gains of the HeadingController parameter and returns itself. 1882 * <p> 1883 * Sets the proportional, integral, and differential coefficients used to maintain 1884 * the desired heading. Users can specify the PID gains to change how aggressively to 1885 * maintain heading. 1886 * <p> 1887 * This PID controller operates on heading radians and outputs a target 1888 * rotational rate in radians per second. 1889 * 1890 * @param kP The proportional coefficient; must be >= 0 1891 * @param kI The integral coefficient; must be >= 0 1892 * @param kD The differential coefficient; must be >= 0 1893 * @return this object 1894 */ 1895 public RobotCentricFacingAngle withHeadingPID(double kP, double kI, double kD) 1896 { 1897 this.HeadingController.setPID(kP, kI, kD); 1898 return this; 1899 } 1900 1901 /** 1902 * Modifies the VelocityX parameter and returns itself. 1903 * <p> 1904 * The velocity in the X direction, in m/s. X is defined as forward according to 1905 * WPILib convention, so this determines how fast to travel forward. 1906 * 1907 * @param newVelocityX Parameter to modify 1908 * @return this object 1909 */ 1910 public RobotCentricFacingAngle withVelocityX(double newVelocityX) { 1911 this.VelocityX = newVelocityX; 1912 return this; 1913 } 1914 1915 /** 1916 * Modifies the VelocityX parameter and returns itself. 1917 * <p> 1918 * The velocity in the X direction, in m/s. X is defined as forward according to 1919 * WPILib convention, so this determines how fast to travel forward. 1920 * 1921 * @param newVelocityX Parameter to modify 1922 * @return this object 1923 */ 1924 public RobotCentricFacingAngle withVelocityX(LinearVelocity newVelocityX) { 1925 this.VelocityX = newVelocityX.in(MetersPerSecond); 1926 return this; 1927 } 1928 1929 /** 1930 * Modifies the VelocityY parameter and returns itself. 1931 * <p> 1932 * The velocity in the Y direction, in m/s. Y is defined as to the left 1933 * according to WPILib convention, so this determines how fast to travel to the 1934 * left. 1935 * 1936 * @param newVelocityY Parameter to modify 1937 * @return this object 1938 */ 1939 public RobotCentricFacingAngle withVelocityY(double newVelocityY) { 1940 this.VelocityY = newVelocityY; 1941 return this; 1942 } 1943 1944 /** 1945 * Modifies the VelocityY parameter and returns itself. 1946 * <p> 1947 * The velocity in the Y direction, in m/s. Y is defined as to the left 1948 * according to WPILib convention, so this determines how fast to travel to the 1949 * left. 1950 * 1951 * @param newVelocityY Parameter to modify 1952 * @return this object 1953 */ 1954 public RobotCentricFacingAngle withVelocityY(LinearVelocity newVelocityY) { 1955 this.VelocityY = newVelocityY.in(MetersPerSecond); 1956 return this; 1957 } 1958 1959 /** 1960 * Modifies the TargetDirection parameter and returns itself. 1961 * <p> 1962 * The desired direction to face. 0 Degrees is defined as in the direction of 1963 * the X axis. As a result, a TargetDirection of 90 degrees will point along 1964 * the Y axis, or to the left. 1965 * 1966 * @param newTargetDirection Parameter to modify 1967 * @return this object 1968 */ 1969 public RobotCentricFacingAngle withTargetDirection(Rotation2d newTargetDirection) { 1970 this.TargetDirection = newTargetDirection; 1971 return this; 1972 } 1973 1974 /** 1975 * Modifies the TargetRateFeedforward parameter and returns itself. 1976 * <p> 1977 * The rotational rate feedforward to add to the output of the heading 1978 * controller, in radians per second. When using a motion profile for the 1979 * target direction, this can be set to the current velocity reference of 1980 * the profile. 1981 * 1982 * @param newTargetRateFeedforward Parameter to modify 1983 * @return this object 1984 */ 1985 public RobotCentricFacingAngle withTargetRateFeedforward(double newTargetRateFeedforward) { 1986 this.TargetRateFeedforward = newTargetRateFeedforward; 1987 return this; 1988 } 1989 /** 1990 * Modifies the TargetRateFeedforward parameter and returns itself. 1991 * <p> 1992 * The rotational rate feedforward to add to the output of the heading 1993 * controller, in radians per second. When using a motion profile for the 1994 * target direction, this can be set to the current velocity reference of 1995 * the profile. 1996 * 1997 * @param newTargetRateFeedforward Parameter to modify 1998 * @return this object 1999 */ 2000 public RobotCentricFacingAngle withTargetRateFeedforward(AngularVelocity newTargetRateFeedforward) { 2001 this.TargetRateFeedforward = newTargetRateFeedforward.in(RadiansPerSecond); 2002 return this; 2003 } 2004 2005 /** 2006 * Modifies the Deadband parameter and returns itself. 2007 * <p> 2008 * The allowable deadband of the request, in m/s. 2009 * 2010 * @param newDeadband Parameter to modify 2011 * @return this object 2012 */ 2013 public RobotCentricFacingAngle withDeadband(double newDeadband) { 2014 this.Deadband = newDeadband; 2015 return this; 2016 } 2017 2018 /** 2019 * Modifies the Deadband parameter and returns itself. 2020 * <p> 2021 * The allowable deadband of the request, in m/s. 2022 * 2023 * @param newDeadband Parameter to modify 2024 * @return this object 2025 */ 2026 public RobotCentricFacingAngle withDeadband(LinearVelocity newDeadband) { 2027 this.Deadband = newDeadband.in(MetersPerSecond); 2028 return this; 2029 } 2030 2031 /** 2032 * Modifies the RotationalDeadband parameter and returns itself. 2033 * <p> 2034 * The rotational deadband of the request, in radians per second. 2035 * 2036 * @param newRotationalDeadband Parameter to modify 2037 * @return this object 2038 */ 2039 public RobotCentricFacingAngle withRotationalDeadband(double newRotationalDeadband) { 2040 this.RotationalDeadband = newRotationalDeadband; 2041 return this; 2042 } 2043 2044 /** 2045 * Modifies the RotationalDeadband parameter and returns itself. 2046 * <p> 2047 * The rotational deadband of the request, in radians per second. 2048 * 2049 * @param newRotationalDeadband Parameter to modify 2050 * @return this object 2051 */ 2052 public RobotCentricFacingAngle withRotationalDeadband(AngularVelocity newRotationalDeadband) { 2053 this.RotationalDeadband = newRotationalDeadband.in(RadiansPerSecond); 2054 return this; 2055 } 2056 2057 /** 2058 * Modifies the MaxAbsRotationalRate parameter and returns itself. 2059 * <p> 2060 * The maximum absolute rotational rate to allow, in radians per second. 2061 * Setting this to 0 results in no cap to rotational rate. 2062 * 2063 * @param newMaxAbsRotationalRate Parameter to modify 2064 * @return this object 2065 */ 2066 public RobotCentricFacingAngle withMaxAbsRotationalRate(double newMaxAbsRotationalRate) { 2067 this.MaxAbsRotationalRate = newMaxAbsRotationalRate; 2068 return this; 2069 } 2070 2071 /** 2072 * Modifies the MaxAbsRotationalRate parameter and returns itself. 2073 * <p> 2074 * The maximum absolute rotational rate to allow, in radians per second. 2075 * Setting this to 0 results in no cap to rotational rate. 2076 * 2077 * @param newMaxAbsRotationalRate Parameter to modify 2078 * @return this object 2079 */ 2080 public RobotCentricFacingAngle withMaxAbsRotationalRate(AngularVelocity newMaxAbsRotationalRate) { 2081 this.MaxAbsRotationalRate = newMaxAbsRotationalRate.in(RadiansPerSecond); 2082 return this; 2083 } 2084 2085 /** 2086 * Modifies the CenterOfRotation parameter and returns itself. 2087 * <p> 2088 * The center of rotation the robot should rotate around. This is (0,0) by 2089 * default, which will rotate around the center of the robot. 2090 * 2091 * @param newCenterOfRotation Parameter to modify 2092 * @return this object 2093 */ 2094 public RobotCentricFacingAngle withCenterOfRotation(Translation2d newCenterOfRotation) { 2095 this.CenterOfRotation = newCenterOfRotation; 2096 return this; 2097 } 2098 2099 /** 2100 * Modifies the DriveRequestType parameter and returns itself. 2101 * <p> 2102 * The type of control request to use for the drive motor. 2103 * 2104 * @param newDriveRequestType Parameter to modify 2105 * @return this object 2106 */ 2107 public RobotCentricFacingAngle withDriveRequestType(SwerveModule.DriveRequestType newDriveRequestType) { 2108 this.DriveRequestType = newDriveRequestType; 2109 return this; 2110 } 2111 2112 /** 2113 * Modifies the SteerRequestType parameter and returns itself. 2114 * <p> 2115 * The type of control request to use for the drive motor. 2116 * 2117 * @param newSteerRequestType Parameter to modify 2118 * @return this object 2119 */ 2120 public RobotCentricFacingAngle withSteerRequestType(SwerveModule.SteerRequestType newSteerRequestType) { 2121 this.SteerRequestType = newSteerRequestType; 2122 return this; 2123 } 2124 2125 /** 2126 * Modifies the DesaturateWheelSpeeds parameter and returns itself. 2127 * <p> 2128 * Whether to desaturate wheel speeds before applying. For more information, see 2129 * the documentation of {@link SwerveDriveKinematics#desaturateWheelSpeeds}. 2130 * 2131 * @param newDesaturateWheelSpeeds Parameter to modify 2132 * @return this object 2133 */ 2134 public RobotCentricFacingAngle withDesaturateWheelSpeeds(boolean newDesaturateWheelSpeeds) { 2135 this.DesaturateWheelSpeeds = newDesaturateWheelSpeeds; 2136 return this; 2137 } 2138 2139 /** 2140 * Modifies the ForwardPerspective parameter and returns itself. 2141 * <p> 2142 * The perspective to use when determining which direction is forward 2143 * for the target heading. 2144 * 2145 * @param newForwardPerspective Parameter to modify 2146 * @return this object 2147 */ 2148 public RobotCentricFacingAngle withForwardPerspective(ForwardPerspectiveValue newForwardPerspective) { 2149 this.ForwardPerspective = newForwardPerspective; 2150 return this; 2151 } 2152 } 2153 2154 /** 2155 * SysId-specific SwerveRequest to characterize the translational 2156 * characteristics of a swerve drivetrain. 2157 */ 2158 public static class SysIdSwerveTranslation implements SwerveRequest { 2159 /** 2160 * Voltage to apply to drive wheels. 2161 */ 2162 public double VoltsToApply = 0; 2163 2164 /** Local reference to a voltage request for the drive motors */ 2165 private final VoltageOut m_driveRequest = new VoltageOut(0); 2166 /** Local reference to a position voltage request for the steer motors */ 2167 private final PositionVoltage m_steerRequest_Voltage = new PositionVoltage(0); 2168 /** Local reference to a position torque current request for the steer motors */ 2169 private final PositionTorqueCurrentFOC m_steerRequest_TorqueCurrent = new PositionTorqueCurrentFOC(0); 2170 2171 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 2172 for (int i = 0; i < modulesToApply.length; ++i) { 2173 switch (modulesToApply[i].getSteerClosedLoopOutputType()) { 2174 case Voltage: 2175 modulesToApply[i].apply( 2176 m_driveRequest.withOutput(VoltsToApply), 2177 m_steerRequest_Voltage.withPosition(0) 2178 ); 2179 break; 2180 case TorqueCurrentFOC: 2181 modulesToApply[i].apply( 2182 m_driveRequest.withOutput(VoltsToApply), 2183 m_steerRequest_TorqueCurrent.withPosition(0) 2184 ); 2185 break; 2186 } 2187 } 2188 return StatusCode.OK; 2189 } 2190 2191 /** 2192 * Sets the voltage to apply to the drive wheels. 2193 * 2194 * @param volts Voltage to apply 2195 * @return this request 2196 */ 2197 public SysIdSwerveTranslation withVolts(double volts) { 2198 VoltsToApply = volts; 2199 return this; 2200 } 2201 /** 2202 * Sets the voltage to apply to the drive wheels. 2203 * 2204 * @param volts Voltage to apply 2205 * @return this request 2206 */ 2207 public SysIdSwerveTranslation withVolts(Voltage volts) { 2208 VoltsToApply = volts.in(Volts); 2209 return this; 2210 } 2211 } 2212 2213 /** 2214 * SysId-specific SwerveRequest to characterize the rotational 2215 * characteristics of a swerve drivetrain. This is useful to 2216 * characterize the heading controller for FieldCentricFacingAngle. 2217 * <p> 2218 * The RotationalRate of this swerve request should be logged. 2219 * When importing the log to SysId, set the "voltage" to 2220 * RotationalRate, "position" to the Pigeon 2 Yaw, and "velocity" 2221 * to the Pigeon 2 AngularVelocityZWorld. Note that the position 2222 * and velocity will both need to be scaled by pi/180. 2223 * <p> 2224 * Alternatively, the MotorVoltage of one of the drive motors can 2225 * be loaded into the SysId "voltage" field, which can be useful 2226 * when determining the MOI of the robot. 2227 */ 2228 public static class SysIdSwerveRotation implements SwerveRequest { 2229 /** 2230 * The angular rate to rotate at, in radians per second. 2231 */ 2232 public double RotationalRate = 0; 2233 2234 /** Local reference to a voltage request for the drive motors */ 2235 private final VoltageOut m_driveRequest = new VoltageOut(0); 2236 /** Local reference to a position voltage request for the steer motors */ 2237 private final PositionVoltage m_steerRequest_Voltage = new PositionVoltage(0); 2238 /** Local reference to a position torque current request for the steer motors */ 2239 private final PositionTorqueCurrentFOC m_steerRequest_TorqueCurrent = new PositionTorqueCurrentFOC(0); 2240 2241 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 2242 for (int i = 0; i < modulesToApply.length; ++i) { 2243 var speedMps = RotationalRate * parameters.moduleLocations[i].getNorm(); 2244 var driveVoltage = speedMps / parameters.kMaxSpeedMps * 12.0; 2245 2246 var angle = parameters.moduleLocations[i].getAngle().plus(Rotation2d.kCCW_90deg); 2247 2248 switch (modulesToApply[i].getSteerClosedLoopOutputType()) { 2249 case Voltage: 2250 modulesToApply[i].apply( 2251 m_driveRequest.withOutput(driveVoltage), 2252 m_steerRequest_Voltage.withPosition(angle.getRotations()) 2253 ); 2254 break; 2255 case TorqueCurrentFOC: 2256 modulesToApply[i].apply( 2257 m_driveRequest.withOutput(driveVoltage), 2258 m_steerRequest_TorqueCurrent.withPosition(angle.getRotations()) 2259 ); 2260 break; 2261 } 2262 } 2263 return StatusCode.OK; 2264 } 2265 2266 /** 2267 * Update the angular rate to rotate at, in radians per second. 2268 * 2269 * @param newRotationalRate Angular rate to rotate at 2270 * @return this request 2271 */ 2272 public SysIdSwerveRotation withRotationalRate(double newRotationalRate) { 2273 RotationalRate = newRotationalRate; 2274 return this; 2275 } 2276 /** 2277 * Update the angular rate to rotate at. 2278 * 2279 * @param newRotationalRate The angular rate to rotate at 2280 * @return this request 2281 */ 2282 public SysIdSwerveRotation withRotationalRate(AngularVelocity newRotationalRate) { 2283 RotationalRate = newRotationalRate.in(RadiansPerSecond); 2284 return this; 2285 } 2286 } 2287 2288 /** 2289 * SysId-specific SwerveRequest to characterize the steer module 2290 * characteristics of a swerve drivetrain. 2291 */ 2292 public static class SysIdSwerveSteerGains implements SwerveRequest { 2293 /** 2294 * Voltage to apply to steer motors. 2295 */ 2296 public double VoltsToApply = 0; 2297 2298 /** Local reference to a coast request for the drive motors */ 2299 private final CoastOut m_driveRequest = new CoastOut(); 2300 /** Local reference to a voltage request for the steer motors */ 2301 private final VoltageOut m_steerRequest = new VoltageOut(0); 2302 2303 public StatusCode apply(SwerveControlParameters parameters, SwerveModule<?, ?, ?>... modulesToApply) { 2304 for (int i = 0; i < modulesToApply.length; ++i) { 2305 modulesToApply[i].apply(m_driveRequest, m_steerRequest.withOutput(VoltsToApply)); 2306 } 2307 return StatusCode.OK; 2308 } 2309 2310 /** 2311 * Sets the voltage to apply to the steer motors. 2312 * 2313 * @param volts Voltage to apply 2314 * @return this request 2315 */ 2316 public SysIdSwerveSteerGains withVolts(double volts) { 2317 VoltsToApply = volts; 2318 return this; 2319 } 2320 /** 2321 * Sets the voltage to apply to the steer motors. 2322 * 2323 * @param volts Voltage to apply 2324 * @return this request 2325 */ 2326 public SysIdSwerveSteerGains withVolts(Voltage volts) { 2327 VoltsToApply = volts.in(Volts); 2328 return this; 2329 } 2330 } 2331}