001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.math.kinematics; 006 007import static edu.wpi.first.units.Units.Meters; 008 009import edu.wpi.first.math.MathSharedStore; 010import edu.wpi.first.math.geometry.Pose2d; 011import edu.wpi.first.math.geometry.Pose3d; 012import edu.wpi.first.math.geometry.Rotation2d; 013import edu.wpi.first.math.geometry.Rotation3d; 014import edu.wpi.first.math.geometry.Translation2d; 015import edu.wpi.first.math.geometry.Translation3d; 016import edu.wpi.first.units.measure.Distance; 017 018/** 019 * Class for differential drive odometry. Odometry allows you to track the robot's position on the 020 * field over the course of a match using readings from 2 encoders and a gyroscope. 021 * 022 * <p>This class is meant to be an easy replacement for {@link DifferentialDriveOdometry}, only 023 * requiring the addition of appropriate conversions between 2D and 3D versions of geometry classes. 024 * (See {@link Pose3d#Pose3d(Pose2d)}, {@link Rotation3d#Rotation3d(Rotation2d)}, {@link 025 * Translation3d#Translation3d(Translation2d)}, and {@link Pose3d#toPose2d()}.) 026 * 027 * <p>Teams can use odometry during the autonomous period for complex tasks like path following. 028 * Furthermore, odometry can be used for latency compensation when using computer-vision systems. 029 * 030 * <p>It is important that you reset your encoders to zero before using this class. Any subsequent 031 * pose resets also require the encoders to be reset to zero. 032 */ 033public class DifferentialDriveOdometry3d extends Odometry3d<DifferentialDriveWheelPositions> { 034 /** 035 * Constructs a DifferentialDriveOdometry3d object. 036 * 037 * @param gyroAngle The angle reported by the gyroscope. 038 * @param leftDistance The distance traveled by the left encoder in meters. 039 * @param rightDistance The distance traveled by the right encoder in meters. 040 * @param initialPose The starting position of the robot on the field. 041 */ 042 public DifferentialDriveOdometry3d( 043 Rotation3d gyroAngle, double leftDistance, double rightDistance, Pose3d initialPose) { 044 super( 045 new DifferentialDriveKinematics(1), 046 gyroAngle, 047 new DifferentialDriveWheelPositions(leftDistance, rightDistance), 048 initialPose); 049 MathSharedStore.reportUsage("DifferentialDriveOdometry3d", ""); 050 } 051 052 /** 053 * Constructs a DifferentialDriveOdometry3d object. 054 * 055 * @param gyroAngle The angle reported by the gyroscope. 056 * @param leftDistance The distance traveled by the left encoder. 057 * @param rightDistance The distance traveled by the right encoder. 058 * @param initialPose The starting position of the robot on the field. 059 */ 060 public DifferentialDriveOdometry3d( 061 Rotation3d gyroAngle, Distance leftDistance, Distance rightDistance, Pose3d initialPose) { 062 this(gyroAngle, leftDistance.in(Meters), rightDistance.in(Meters), initialPose); 063 } 064 065 /** 066 * Constructs a DifferentialDriveOdometry3d object. 067 * 068 * @param gyroAngle The angle reported by the gyroscope. 069 * @param leftDistance The distance traveled by the left encoder in meters. 070 * @param rightDistance The distance traveled by the right encoder in meters. 071 */ 072 public DifferentialDriveOdometry3d( 073 Rotation3d gyroAngle, double leftDistance, double rightDistance) { 074 this(gyroAngle, leftDistance, rightDistance, Pose3d.kZero); 075 } 076 077 /** 078 * Constructs a DifferentialDriveOdometry3d object. 079 * 080 * @param gyroAngle The angle reported by the gyroscope. 081 * @param leftDistance The distance traveled by the left encoder. 082 * @param rightDistance The distance traveled by the right encoder. 083 */ 084 public DifferentialDriveOdometry3d( 085 Rotation3d gyroAngle, Distance leftDistance, Distance rightDistance) { 086 this(gyroAngle, leftDistance, rightDistance, Pose3d.kZero); 087 } 088 089 /** 090 * Resets the robot's position on the field. 091 * 092 * <p>The gyroscope angle does not need to be reset here on the user's robot code. The library 093 * automatically takes care of offsetting the gyro angle. 094 * 095 * @param gyroAngle The angle reported by the gyroscope. 096 * @param leftDistance The distance traveled by the left encoder in meters. 097 * @param rightDistance The distance traveled by the right encoder in meters. 098 * @param pose The position on the field that your robot is at. 099 */ 100 public void resetPosition( 101 Rotation3d gyroAngle, double leftDistance, double rightDistance, Pose3d pose) { 102 super.resetPosition( 103 gyroAngle, new DifferentialDriveWheelPositions(leftDistance, rightDistance), pose); 104 } 105 106 /** 107 * Resets the robot's position on the field. 108 * 109 * <p>The gyroscope angle does not need to be reset here on the user's robot code. The library 110 * automatically takes care of offsetting the gyro angle. 111 * 112 * @param gyroAngle The angle reported by the gyroscope. 113 * @param leftDistance The distance traveled by the left encoder. 114 * @param rightDistance The distance traveled by the right encoder. 115 * @param pose The position on the field that your robot is at. 116 */ 117 public void resetPosition( 118 Rotation3d gyroAngle, Distance leftDistance, Distance rightDistance, Pose3d pose) { 119 resetPosition(gyroAngle, leftDistance.in(Meters), rightDistance.in(Meters), pose); 120 } 121 122 /** 123 * Updates the robot position on the field using distance measurements from encoders. This method 124 * is more numerically accurate than using velocities to integrate the pose and is also 125 * advantageous for teams that are using lower CPR encoders. 126 * 127 * @param gyroAngle The angle reported by the gyroscope. 128 * @param leftDistance The distance traveled by the left encoder in meters. 129 * @param rightDistance The distance traveled by the right encoder in meters. 130 * @return The new pose of the robot. 131 */ 132 public Pose3d update(Rotation3d gyroAngle, double leftDistance, double rightDistance) { 133 return super.update( 134 gyroAngle, new DifferentialDriveWheelPositions(leftDistance, rightDistance)); 135 } 136}