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