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 java.nio.ByteBuffer; 011import java.nio.ByteOrder; 012 013import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType; 014import edu.wpi.first.wpilibj.hal.AnalogJNI; 015import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType; 016import edu.wpi.first.wpilibj.hal.HAL; 017import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder; 018import edu.wpi.first.wpilibj.util.BoundaryException; 019 020/** 021 * Class for creating and configuring Analog Triggers. 022 */ 023public class AnalogTrigger extends SensorBase implements Sendable { 024 /** 025 * Exceptions dealing with improper operation of the Analog trigger. 026 */ 027 public class AnalogTriggerException extends RuntimeException { 028 /** 029 * Create a new exception with the given message. 030 * 031 * @param message the message to pass with the exception 032 */ 033 public AnalogTriggerException(String message) { 034 super(message); 035 } 036 037 } 038 039 /** 040 * Where the analog trigger is attached. 041 */ 042 protected int m_port; 043 protected int m_index; 044 protected AnalogInput m_analogInput = null; 045 protected boolean m_ownsAnalog = false; 046 047 /** 048 * Constructor for an analog trigger given a channel number. 049 * 050 * @param channel the port to use for the analog trigger 051 */ 052 public AnalogTrigger(final int channel) { 053 this(new AnalogInput(channel)); 054 m_ownsAnalog = true; 055 addChild(m_analogInput); 056 } 057 058 /** 059 * Construct an analog trigger given an analog channel. This should be used in the case of sharing 060 * an analog channel between the trigger and an analog input object. 061 * 062 * @param channel the AnalogInput to use for the analog trigger 063 */ 064 public AnalogTrigger(AnalogInput channel) { 065 m_analogInput = channel; 066 ByteBuffer index = ByteBuffer.allocateDirect(4); 067 index.order(ByteOrder.LITTLE_ENDIAN); 068 069 m_port = 070 AnalogJNI.initializeAnalogTrigger(channel.m_port, index.asIntBuffer()); 071 m_index = index.asIntBuffer().get(0); 072 073 HAL.report(tResourceType.kResourceType_AnalogTrigger, channel.getChannel()); 074 setName("AnalogTrigger", channel.getChannel()); 075 } 076 077 /** 078 * Release the resources used by this object. 079 */ 080 @Override 081 public void free() { 082 super.free(); 083 AnalogJNI.cleanAnalogTrigger(m_port); 084 m_port = 0; 085 if (m_ownsAnalog && m_analogInput != null) { 086 m_analogInput.free(); 087 } 088 } 089 090 /** 091 * Set the upper and lower limits of the analog trigger. The limits are given in ADC codes. If 092 * oversampling is used, the units must be scaled appropriately. 093 * 094 * @param lower the lower raw limit 095 * @param upper the upper raw limit 096 */ 097 public void setLimitsRaw(final int lower, final int upper) { 098 if (lower > upper) { 099 throw new BoundaryException("Lower bound is greater than upper"); 100 } 101 AnalogJNI.setAnalogTriggerLimitsRaw(m_port, lower, upper); 102 } 103 104 /** 105 * Set the upper and lower limits of the analog trigger. The limits are given as floating point 106 * voltage values. 107 * 108 * @param lower the lower voltage limit 109 * @param upper the upper voltage limit 110 */ 111 public void setLimitsVoltage(double lower, double upper) { 112 if (lower > upper) { 113 throw new BoundaryException("Lower bound is greater than upper bound"); 114 } 115 AnalogJNI.setAnalogTriggerLimitsVoltage(m_port, lower, upper); 116 } 117 118 /** 119 * Configure the analog trigger to use the averaged vs. raw values. If the value is true, then the 120 * averaged value is selected for the analog trigger, otherwise the immediate value is used. 121 * 122 * @param useAveragedValue true to use an averaged value, false otherwise 123 */ 124 public void setAveraged(boolean useAveragedValue) { 125 AnalogJNI.setAnalogTriggerAveraged(m_port, useAveragedValue); 126 } 127 128 /** 129 * Configure the analog trigger to use a filtered value. The analog trigger will operate with a 3 130 * point average rejection filter. This is designed to help with 360 degree pot applications for 131 * the period where the pot crosses through zero. 132 * 133 * @param useFilteredValue true to use a filtered value, false otherwise 134 */ 135 public void setFiltered(boolean useFilteredValue) { 136 AnalogJNI.setAnalogTriggerFiltered(m_port, useFilteredValue); 137 } 138 139 /** 140 * Return the index of the analog trigger. This is the FPGA index of this analog trigger 141 * instance. 142 * 143 * @return The index of the analog trigger. 144 */ 145 public int getIndex() { 146 return m_index; 147 } 148 149 /** 150 * Return the InWindow output of the analog trigger. True if the analog input is between the upper 151 * and lower limits. 152 * 153 * @return The InWindow output of the analog trigger. 154 */ 155 public boolean getInWindow() { 156 return AnalogJNI.getAnalogTriggerInWindow(m_port); 157 } 158 159 /** 160 * Return the TriggerState output of the analog trigger. True if above upper limit. False if below 161 * lower limit. If in Hysteresis, maintain previous state. 162 * 163 * @return The TriggerState output of the analog trigger. 164 */ 165 public boolean getTriggerState() { 166 return AnalogJNI.getAnalogTriggerTriggerState(m_port); 167 } 168 169 /** 170 * Creates an AnalogTriggerOutput object. Gets an output object that can be used for routing. 171 * Caller is responsible for deleting the AnalogTriggerOutput object. 172 * 173 * @param type An enum of the type of output object to create. 174 * @return A pointer to a new AnalogTriggerOutput object. 175 */ 176 public AnalogTriggerOutput createOutput(AnalogTriggerType type) { 177 return new AnalogTriggerOutput(this, type); 178 } 179 180 @Override 181 public void initSendable(SendableBuilder builder) { 182 if (m_ownsAnalog) { 183 m_analogInput.initSendable(builder); 184 } 185 } 186}