001package com.ctre.phoenix.motorcontrol; 002 003import com.ctre.phoenix.ErrorCode; 004import com.ctre.phoenix.motorcontrol.can.BaseTalon; 005import com.ctre.phoenix.motorcontrol.can.MotControllerJNI; 006 007/** 008 * Collection of sensors available to a motor controller. 009 * 010 * For best performance and update-rate, 011 * we recommend using the configSelectedFeedbackSensor() and getSelectedSensor*() routines. 012 * However there are occasions where accessing raw sensor values may be useful or convenient. 013 * Particularly if you are seeding one sensor based on another, or need to circumvent sensor-phase. 014 * 015 * Use the getSensorCollection() routine inside your motor controller to create a sensor collection. 016 */ 017public class SensorCollection { 018 019 private long _handle; 020 021 /** 022 * Constructor for SensorCollection 023 * @param motorController Motor Controller to connect Collection to 024 */ 025 public SensorCollection(BaseTalon motorController) { 026 _handle = motorController.getHandle(); 027 } 028 029 /** 030 * Get the position of whatever is in the analog pin of the Talon, regardless of 031 * whether it is actually being used for feedback. 032 * <p> 033 * This method relies on the Status 4 message, which has a default period of 150ms. For more 034 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 035 * 036 * @return the 24bit analog value. The bottom ten bits is the ADC (0 - 1023) 037 * on the analog pin of the Talon. The upper 14 bits tracks the overflows and underflows 038 * (continuous sensor). 039 */ 040 041 public int getAnalogIn() { 042 return MotControllerJNI.GetAnalogIn(_handle); 043 } 044 045 /** 046 * Sets analog position. 047 * 048 * @param newPosition The new position. 049 * @param timeoutMs 050 * Timeout value in ms. If nonzero, function will wait for 051 * config success and report an error if it times out. 052 * If zero, no blocking or checking is performed. 053 * 054 * @return an ErrorCode. 055 */ 056 057 public ErrorCode setAnalogPosition(int newPosition, int timeoutMs) { 058 int retval = MotControllerJNI.SetAnalogPosition(_handle, newPosition, timeoutMs); 059 return ErrorCode.valueOf(retval); 060 } 061 062 /** 063 * Get the position of whatever is in the analog pin of the Talon, regardless of whether 064 * it is actually being used for feedback. 065 * <p> 066 * This method relies on the Status 4 message, which has a default period of 150ms. For more 067 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 068 * 069 * @return the ADC (0 - 1023) on analog pin of the Talon. 070 */ 071 072 public int getAnalogInRaw() { 073 return MotControllerJNI.GetAnalogInRaw(_handle); 074 } 075 076 /** 077 * Get the velocity of whatever is in the analog pin of the Talon, regardless of 078 * whether it is actually being used for feedback. 079 * <p> 080 * This method relies on the Status 4 message, which has a default period of 150ms. For more 081 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 082 * 083 * @return the speed in units per 100ms where 1024 units is one rotation. 084 */ 085 086 public int getAnalogInVel() { 087 return MotControllerJNI.GetAnalogInVel(_handle); 088 } 089 090 /** 091 * Get the quadrature position of the Talon, regardless of whether 092 * it is actually being used for feedback. 093 * <p> 094 * This method relies on the Status 3 message, which has a default period of 150ms. For more 095 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 096 * 097 * @return the quadrature position. 098 */ 099 100 public int getQuadraturePosition() { 101 return MotControllerJNI.GetQuadraturePosition(_handle); 102 } 103 104 /** 105 * Change the quadrature reported position. Typically this is used to "zero" the 106 * sensor. This only works with Quadrature sensor. To set the selected sensor position 107 * regardless of what type it is, see SetSelectedSensorPosition in the motor controller class. 108 * 109 * @param newPosition The position value to apply to the sensor. 110 * @param timeoutMs 111 * Timeout value in ms. If nonzero, function will wait for 112 * config success and report an error if it times out. 113 * If zero, no blocking or checking is performed. 114 * 115 * @return error code. 116 */ 117 118 public ErrorCode setQuadraturePosition(int newPosition, int timeoutMs) { 119 int retval = MotControllerJNI.SetQuadraturePosition(_handle, newPosition, timeoutMs); 120 return ErrorCode.valueOf(retval); 121 } 122 123 124 /** 125 * Change the quadrature reported position based on pulse width. This can be used to 126 * effectively make quadrature absolute. For rotary mechanisms with >360 movement (such 127 * as typical swerve modules) bookend0 and bookend1 can be both set to 0 and 128 * bCrossZeroOnInterval can be set to true. For mechanisms with less than 360 travel (such 129 * as arms), bookend0 and bookend1 should be set to the pulse width values at the two 130 * extremes. If the interval crosses over the pulse width value of 0 (or any multiple of 131 * 4096), bCrossZeroOnInterval should be true and otherwise should be false. An offset can 132 * also be set. 133 * 134 * @param bookend0 value at extreme 0 135 * @param bookend1 value at extreme 1 136 * @param bCrossZeroOnInterval True iff zero/wrap-around cross occurs as mechanism moves from bookend0 to bookend1. 137 * @param offset (Optional) Value to add to pulse width 138 * @param timeoutMs (Optional) How long to wait for confirmation. Pass zero so that call 139 * does not block. 140 * 141 * @return error code. 142 */ 143 144 public ErrorCode syncQuadratureWithPulseWidth(int bookend0, int bookend1, boolean bCrossZeroOnInterval, int offset, int timeoutMs) { 145 int ticksPerRevolution = 4096; 146 /* Normalize bookends (should be 0 - ticksPerRevolution) */ 147 bookend0 &= (ticksPerRevolution - 1); 148 bookend1 &= (ticksPerRevolution - 1); 149 150 /* Assign greater and lesser bookend */ 151 int greaterBookend; 152 int lesserBookend; 153 154 if(bookend0 > bookend1) 155 { 156 greaterBookend = bookend0; 157 lesserBookend = bookend1; 158 } 159 else 160 { 161 greaterBookend = bookend1; 162 lesserBookend = bookend0; 163 } 164 165 int average = (greaterBookend + lesserBookend) / 2; 166 167 /* Get Fractional Part of Pulse Width Position (0 - ticksPerRevolution) */ 168 int pulseWidth = getPulseWidthPosition(); 169 pulseWidth &= (ticksPerRevolution - 1); 170 171 if(bCrossZeroOnInterval) 172 { 173 /* 174 * If the desire is to have the *** part be the interval 175 * (2048 - 3277 and crosses over 0): 176 * 177 * 178 * 1024 179 * ********* 180 * *********** 181 * ************* 182 * *************** 183 * ***************** 184 * ***************** 185 * ***************** 186 * 2048 ***************** 0 187 * ********* 188 * ********* 189 * ********* 190 * ********* 191 * ********** 192 * ********* 193 * ******** 194 * ******** 195 * ******* 196 * 3277 197 * 198 * The goal is to center the discontinuoity between 2048 and 3277 in the blank. 199 * So all pulse width values greater than the avg of the two bookends should be 200 * reduced by ticksPerRevolution. 201 */ 202 if(pulseWidth > average) 203 { 204 pulseWidth -= ticksPerRevolution; 205 } 206 } 207 else 208 { 209 /* 210 * If the desire is to have the blank part be the interval 211 * (2048 - 3277 and crosses over 0): 212 * 213 * 214 * 1024 215 * ********* 216 * *********** 217 * ************* 218 * *************** 219 * ***************** 220 * ***************** 221 * ***************** 222 * 2048 ***************** 0 223 * ********* 224 * ********* 225 * ********* 226 * ********* 227 * ********** 228 * ********* 229 * ******** 230 * ******** 231 * ******* 232 * 3277 233 * 234 * The goal is to center the discontinuoity between 2048 and 3277 in the ***. 235 * So all pulse width values less than the (ticksPerRevolution / 2 - avg of 236 * the two bookends) & ticksPerRevolution should be increased by 237 * ticksPerRevolution. 238 */ 239 if(pulseWidth < ((ticksPerRevolution / 2 - average) & 0x0FFF)) 240 { 241 pulseWidth += ticksPerRevolution; 242 } 243 } 244 245 pulseWidth += offset; 246 247 return setQuadraturePosition(pulseWidth, timeoutMs); 248 } 249 250 /** 251 * Change the quadrature reported position based on pulse width. This can be used to 252 * effectively make quadrature absolute. For rotary mechanisms with >360 movement (such 253 * as typical swerve modules) bookend0 and bookend1 can be both set to 0 and 254 * bCrossZeroOnInterval can be set to true. For mechanisms with less than 360 travel (such 255 * as arms), bookend0 and bookend1 should be set to the pulse width values at the two 256 * extremes. If the interval crosses over the pulse width value of 0 (or any multiple of 257 * 4096), bCrossZeroOnInterval should be true and otherwise should be false. An offset can 258 * also be set. 259 * 260 * @param bookend0 value at extreme 0 261 * @param bookend1 value at extreme 1 262 * @param bCrossZeroOnInterval True iff zero/wrap-around cross occurs as mechanism moves from bookend0 to bookend1. 263 * 264 * @return error code. 265 */ 266 public ErrorCode syncQuadratureWithPulseWidth(int bookend0, int bookend1, boolean bCrossZeroOnInterval) { 267 int offset = 0; 268 int timeoutMs = 0; 269 return syncQuadratureWithPulseWidth(bookend0, bookend1, bCrossZeroOnInterval, offset, timeoutMs); 270 } 271 /** 272 * Get the quadrature velocity, regardless of whether 273 * it is actually being used for feedback. 274 * <p> 275 * This method relies on the Status 3 message, which has a default period of 150ms. For more 276 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 277 * 278 * @return the quadrature velocity in units per 100ms. 279 */ 280 281 public int getQuadratureVelocity() { 282 return MotControllerJNI.GetQuadratureVelocity(_handle); 283 } 284 285 /** 286 * Gets pulse width position, regardless of whether 287 * it is actually being used for feedback. 288 * <p> 289 * This method relies on the Status 8 message, which has a default period of 150ms. For more 290 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 291 * 292 * @return the pulse width position. 293 */ 294 295 public int getPulseWidthPosition() { 296 return MotControllerJNI.GetPulseWidthPosition(_handle); 297 } 298 299 /** 300 * Sets pulse width position. 301 * 302 * @param newPosition The position value to apply to the sensor. 303 * @param timeoutMs 304 * Timeout value in ms. If nonzero, function will wait for 305 * config success and report an error if it times out. 306 * If zero, no blocking or checking is performed. 307 * 308 * @return an ErrErrorCode 309 */ 310 public ErrorCode setPulseWidthPosition(int newPosition, int timeoutMs) { 311 int retval = MotControllerJNI.SetPulseWidthPosition(_handle, newPosition, timeoutMs); 312 return ErrorCode.valueOf(retval); 313 } 314 315 /** 316 * Gets pulse width velocity, regardless of whether 317 * it is actually being used for feedback. 318 * <p> 319 * This method relies on the Status 8 message, which has a default period of 150ms. For more 320 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 321 * 322 * @return the pulse width velocity in units per 100ms (where 4096 units is 1 rotation). 323 */ 324 325 public int getPulseWidthVelocity() { 326 return MotControllerJNI.GetPulseWidthVelocity(_handle); 327 } 328 329 /** 330 * Gets pulse width rise to fall time. 331 * <p> 332 * This method relies on the Status 8 message, which has a default period of 150ms. For more 333 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 334 * 335 * @return the pulse width rise to fall time in microseconds. 336 */ 337 338 public int getPulseWidthRiseToFallUs() { 339 return MotControllerJNI.GetPulseWidthRiseToFallUs(_handle); 340 } 341 342 /** 343 * Gets pulse width rise to rise time. 344 * <p> 345 * This method relies on the Status 8 message, which has a default period of 150ms. For more 346 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 347 * 348 * @return the pulse width rise to rise time in microseconds. 349 */ 350 351 public int getPulseWidthRiseToRiseUs() { 352 return MotControllerJNI.GetPulseWidthRiseToRiseUs(_handle); 353 } 354 355 /** 356 * Gets pin state quad a. 357 * <p> 358 * This method relies on the Status 3 message, which has a default period of 150ms. For more 359 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 360 * 361 * @return the pin state of quad a (1 if asserted, 0 if not asserted). 362 */ 363 364 public boolean getPinStateQuadA() { 365 return MotControllerJNI.GetPinStateQuadA(_handle) != 0; 366 } 367 368 /** 369 * Gets pin state quad b. 370 * <p> 371 * This method relies on the Status 3 message, which has a default period of 150ms. For more 372 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 373 * 374 * @return Digital level of QUADB pin (1 if asserted, 0 if not asserted). 375 */ 376 377 public boolean getPinStateQuadB() { 378 return MotControllerJNI.GetPinStateQuadB(_handle) != 0; 379 } 380 381 /** 382 * Gets pin state quad index. 383 * <p> 384 * This method relies on the Status 3 message, which has a default period of 150ms. For more 385 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 386 * 387 * @return Digital level of QUAD Index pin (1 if asserted, 0 if not asserted). 388 */ 389 390 public boolean getPinStateQuadIdx() { 391 return MotControllerJNI.GetPinStateQuadIdx(_handle) != 0; 392 } 393 394 /** 395 * Is forward limit switch closed. 396 * <p> 397 * This method relies on the Status 1 message, which has a default period of 10ms. For more 398 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 399 * 400 * @return '1' iff forward limit switch is closed, 0 iff switch is open. This function works 401 * regardless if limit switch feature is enabled. Remote limit features do not impact this routine. 402 */ 403 404 public boolean isFwdLimitSwitchClosed() { 405 return MotControllerJNI.IsFwdLimitSwitchClosed(_handle) != 0; 406 } 407 408 /** 409 * Is reverse limit switch closed. 410 * <p> 411 * This method relies on the Status 1 message, which has a default period of 10ms. For more 412 * information, see: https://phoenix-documentation.readthedocs.io/en/latest/ch18_CommonAPI.html 413 * 414 * @return '1' iff reverse limit switch is closed, 0 iff switch is open. This function works 415 * regardless if limit switch feature is enabled. Remote limit features do not impact this routine. 416 */ 417 418 public boolean isRevLimitSwitchClosed() { 419 return MotControllerJNI.IsRevLimitSwitchClosed(_handle) != 0; 420 } 421}