001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */ 003/* Open Source Software - may be modified and shared by FRC teams. The code */ 004/* must be accompanied by the FIRST BSD license file in the root directory of */ 005/* the project. */ 006/*----------------------------------------------------------------------------*/ 007 008package edu.wpi.first.wpilibj; 009 010import edu.wpi.first.wpilibj.hal.AnalogGyroJNI; 011import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType; 012import edu.wpi.first.wpilibj.hal.HAL; 013import edu.wpi.first.wpilibj.interfaces.Gyro; 014 015import static java.util.Objects.requireNonNull; 016 017/** 018 * Use a rate gyro to return the robots heading relative to a starting position. The Gyro class 019 * tracks the robots heading based on the starting position. As the robot rotates the new heading is 020 * computed by integrating the rate of rotation returned by the sensor. When the class is 021 * instantiated, it does a short calibration routine where it samples the gyro while at rest to 022 * determine the default offset. This is subtracted from each sample to determine the heading. 023 * 024 * <p>This class is for gyro sensors that connect to an analog input. 025 */ 026public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable { 027 private static final double kDefaultVoltsPerDegreePerSecond = 0.007; 028 protected AnalogInput m_analog; 029 private boolean m_channelAllocated = false; 030 031 private int m_gyroHandle = 0; 032 033 /** 034 * Initialize the gyro. Calibration is handled by calibrate(). 035 */ 036 public void initGyro() { 037 if (m_gyroHandle == 0) { 038 m_gyroHandle = AnalogGyroJNI.initializeAnalogGyro(m_analog.m_port); 039 } 040 041 AnalogGyroJNI.setupAnalogGyro(m_gyroHandle); 042 043 HAL.report(tResourceType.kResourceType_Gyro, m_analog.getChannel()); 044 setName("AnalogGyro", m_analog.getChannel()); 045 } 046 047 @Override 048 public void calibrate() { 049 AnalogGyroJNI.calibrateAnalogGyro(m_gyroHandle); 050 } 051 052 /** 053 * Gyro constructor using the channel number. 054 * 055 * @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board 056 * channels 0-1. 057 */ 058 public AnalogGyro(int channel) { 059 this(new AnalogInput(channel)); 060 m_channelAllocated = true; 061 addChild(m_analog); 062 } 063 064 /** 065 * Gyro constructor with a precreated analog channel object. Use this constructor when the analog 066 * channel needs to be shared. 067 * 068 * @param channel The AnalogInput object that the gyro is connected to. Gyros can only be used on 069 * on-board channels 0-1. 070 */ 071 public AnalogGyro(AnalogInput channel) { 072 requireNonNull(channel, "AnalogInput supplied to Gyro constructor is null"); 073 074 m_analog = channel; 075 initGyro(); 076 calibrate(); 077 } 078 079 /** 080 * Gyro constructor using the channel number along with parameters for presetting the center and 081 * offset values. Bypasses calibration. 082 * 083 * @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board 084 * channels 0-1. 085 * @param center Preset uncalibrated value to use as the accumulator center value. 086 * @param offset Preset uncalibrated value to use as the gyro offset. 087 */ 088 public AnalogGyro(int channel, int center, double offset) { 089 this(new AnalogInput(channel), center, offset); 090 m_channelAllocated = true; 091 addChild(m_analog); 092 } 093 094 /** 095 * Gyro constructor with a precreated analog channel object along with parameters for presetting 096 * the center and offset values. Bypasses calibration. 097 * 098 * @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board 099 * channels 0-1. 100 * @param center Preset uncalibrated value to use as the accumulator center value. 101 * @param offset Preset uncalibrated value to use as the gyro offset. 102 */ 103 public AnalogGyro(AnalogInput channel, int center, double offset) { 104 requireNonNull(channel, "AnalogInput supplied to Gyro constructor is null"); 105 106 m_analog = channel; 107 initGyro(); 108 AnalogGyroJNI.setAnalogGyroParameters(m_gyroHandle, kDefaultVoltsPerDegreePerSecond, 109 offset, center); 110 reset(); 111 } 112 113 @Override 114 public void reset() { 115 AnalogGyroJNI.resetAnalogGyro(m_gyroHandle); 116 } 117 118 /** 119 * Delete (free) the accumulator and the analog components used for the gyro. 120 */ 121 @Override 122 public void free() { 123 super.free(); 124 if (m_analog != null && m_channelAllocated) { 125 m_analog.free(); 126 } 127 m_analog = null; 128 AnalogGyroJNI.freeAnalogGyro(m_gyroHandle); 129 } 130 131 @Override 132 public double getAngle() { 133 if (m_analog == null) { 134 return 0.0; 135 } else { 136 return AnalogGyroJNI.getAnalogGyroAngle(m_gyroHandle); 137 } 138 } 139 140 @Override 141 public double getRate() { 142 if (m_analog == null) { 143 return 0.0; 144 } else { 145 return AnalogGyroJNI.getAnalogGyroRate(m_gyroHandle); 146 } 147 } 148 149 /** 150 * Return the gyro offset value set during calibration to use as a future preset. 151 * 152 * @return the current offset value 153 */ 154 public double getOffset() { 155 return AnalogGyroJNI.getAnalogGyroOffset(m_gyroHandle); 156 } 157 158 /** 159 * Return the gyro center value set during calibration to use as a future preset. 160 * 161 * @return the current center value 162 */ 163 public int getCenter() { 164 return AnalogGyroJNI.getAnalogGyroCenter(m_gyroHandle); 165 } 166 167 /** 168 * Set the gyro sensitivity. This takes the number of volts/degree/second sensitivity of the gyro 169 * and uses it in subsequent calculations to allow the code to work with multiple gyros. This 170 * value is typically found in the gyro datasheet. 171 * 172 * @param voltsPerDegreePerSecond The sensitivity in Volts/degree/second. 173 */ 174 public void setSensitivity(double voltsPerDegreePerSecond) { 175 AnalogGyroJNI.setAnalogGyroVoltsPerDegreePerSecond(m_gyroHandle, 176 voltsPerDegreePerSecond); 177 } 178 179 /** 180 * Set the size of the neutral zone. Any voltage from the gyro less than this amount from the 181 * center is considered stationary. Setting a deadband will decrease the amount of drift when the 182 * gyro isn't rotating, but will make it less accurate. 183 * 184 * @param volts The size of the deadband in volts 185 */ 186 void setDeadband(double volts) { 187 AnalogGyroJNI.setAnalogGyroDeadband(m_gyroHandle, volts); 188 } 189}