001/* 002 * Copyright (C) Cross The Road Electronics. All rights reserved. 003 * License information can be found in CTRE_LICENSE.txt 004 * For support and suggestions contact support@ctr-electronics.com or file 005 * an issue tracker at https://github.com/CrossTheRoadElec/Phoenix-Releases 006 */ 007package com.ctre.phoenix6.configs; 008 009import com.ctre.phoenix6.StatusCode; 010import com.ctre.phoenix6.configs.jni.ConfigJNI; 011import com.ctre.phoenix6.spns.*; 012import com.ctre.phoenix6.signals.*; 013 014import edu.wpi.first.units.*; 015 016import edu.wpi.first.units.measure.*; 017import static edu.wpi.first.units.Units.*; 018 019/** 020 * Configs that affect the magnet sensor and how to interpret it. 021 * <p> 022 * Includes sensor direction, the sensor discontinuity point, and the 023 * magnet offset. 024 */ 025public class MagnetSensorConfigs implements ParentConfiguration 026{ 027 /** 028 * Direction of the sensor to determine positive rotation, as seen 029 * facing the LED side of the CANcoder. 030 * 031 */ 032 public SensorDirectionValue SensorDirection = SensorDirectionValue.CounterClockwise_Positive; 033 /** 034 * This offset is added to the reported position, allowing the 035 * application to trim the zero position. When set to the default 036 * value of zero, position reports zero when magnet north pole aligns 037 * with the LED. 038 * 039 * <ul> 040 * <li> <b>Minimum Value:</b> -1 041 * <li> <b>Maximum Value:</b> 1 042 * <li> <b>Default Value:</b> 0 043 * <li> <b>Units:</b> rotations 044 * </ul> 045 */ 046 public double MagnetOffset = 0; 047 /** 048 * The positive discontinuity point of the absolute sensor in 049 * rotations. This determines the point at which the absolute sensor 050 * wraps around, keeping the absolute position (after offset) in the 051 * range [x-1, x). 052 * 053 * <ul> 054 * <li> Setting this to 1 makes the absolute position unsigned [0, 055 * 1) 056 * <li> Setting this to 0.5 makes the absolute position signed 057 * [-0.5, 0.5) 058 * <li> Setting this to 0 makes the absolute position always 059 * negative [-1, 0) 060 * </ul> 061 * 062 * Many rotational mechanisms such as arms have a region of motion 063 * that is unreachable. This should be set to the center of that 064 * region of motion, in non-negative rotations. This affects the 065 * position of the device at bootup. 066 * <p> 067 * For example, consider an arm which can travel from -0.2 to 0.6 068 * rotations with a little leeway, where 0 is horizontally forward. 069 * Since -0.2 rotations has the same absolute position as 0.8 070 * rotations, we can say that the arm typically does not travel in the 071 * range (0.6, 0.8) rotations. As a result, the discontinuity point 072 * would be the center of that range, which is 0.7 rotations. This 073 * results in an absolute sensor range of [-0.3, 0.7) rotations. 074 * <p> 075 * Given a total range of motion less than 1 rotation, users can 076 * calculate the discontinuity point using mean(lowerLimit, 077 * upperLimit) + 0.5. If that results in a value outside the range [0, 078 * 1], either cap the value to [0, 1], or add/subtract 1.0 rotation 079 * from your lower and upper limits of motion. 080 * <p> 081 * On a Talon motor controller, this is only supported when using the 082 * PulseWidth sensor source. 083 * 084 * <ul> 085 * <li> <b>Minimum Value:</b> 0.0 086 * <li> <b>Maximum Value:</b> 1.0 087 * <li> <b>Default Value:</b> 0.5 088 * <li> <b>Units:</b> rotations 089 * </ul> 090 */ 091 public double AbsoluteSensorDiscontinuityPoint = 0.5; 092 093 /** 094 * Modifies this configuration's SensorDirection parameter and returns itself for 095 * method-chaining and easier to use config API. 096 * <p> 097 * Direction of the sensor to determine positive rotation, as seen 098 * facing the LED side of the CANcoder. 099 * 100 * 101 * @param newSensorDirection Parameter to modify 102 * @return Itself 103 */ 104 public MagnetSensorConfigs withSensorDirection(SensorDirectionValue newSensorDirection) 105 { 106 SensorDirection = newSensorDirection; 107 return this; 108 } 109 110 /** 111 * Modifies this configuration's MagnetOffset parameter and returns itself for 112 * method-chaining and easier to use config API. 113 * <p> 114 * This offset is added to the reported position, allowing the 115 * application to trim the zero position. When set to the default 116 * value of zero, position reports zero when magnet north pole aligns 117 * with the LED. 118 * 119 * <ul> 120 * <li> <b>Minimum Value:</b> -1 121 * <li> <b>Maximum Value:</b> 1 122 * <li> <b>Default Value:</b> 0 123 * <li> <b>Units:</b> rotations 124 * </ul> 125 * 126 * @param newMagnetOffset Parameter to modify 127 * @return Itself 128 */ 129 public MagnetSensorConfigs withMagnetOffset(double newMagnetOffset) 130 { 131 MagnetOffset = newMagnetOffset; 132 return this; 133 } 134 135 /** 136 * Modifies this configuration's MagnetOffset parameter and returns itself for 137 * method-chaining and easier to use config API. 138 * <p> 139 * This offset is added to the reported position, allowing the 140 * application to trim the zero position. When set to the default 141 * value of zero, position reports zero when magnet north pole aligns 142 * with the LED. 143 * 144 * <ul> 145 * <li> <b>Minimum Value:</b> -1 146 * <li> <b>Maximum Value:</b> 1 147 * <li> <b>Default Value:</b> 0 148 * <li> <b>Units:</b> rotations 149 * </ul> 150 * 151 * @param newMagnetOffset Parameter to modify 152 * @return Itself 153 */ 154 public MagnetSensorConfigs withMagnetOffset(Angle newMagnetOffset) 155 { 156 MagnetOffset = newMagnetOffset.in(Rotations); 157 return this; 158 } 159 160 /** 161 * Helper method to get this configuration's MagnetOffset parameter converted 162 * to a unit type. If not using the Java units library, {@link #MagnetOffset} 163 * can be accessed directly instead. 164 * <p> 165 * This offset is added to the reported position, allowing the 166 * application to trim the zero position. When set to the default 167 * value of zero, position reports zero when magnet north pole aligns 168 * with the LED. 169 * 170 * <ul> 171 * <li> <b>Minimum Value:</b> -1 172 * <li> <b>Maximum Value:</b> 1 173 * <li> <b>Default Value:</b> 0 174 * <li> <b>Units:</b> rotations 175 * </ul> 176 * 177 * @return MagnetOffset 178 */ 179 public Angle getMagnetOffsetMeasure() 180 { 181 return Rotations.of(MagnetOffset); 182 } 183 184 /** 185 * Modifies this configuration's AbsoluteSensorDiscontinuityPoint parameter and returns itself for 186 * method-chaining and easier to use config API. 187 * <p> 188 * The positive discontinuity point of the absolute sensor in 189 * rotations. This determines the point at which the absolute sensor 190 * wraps around, keeping the absolute position (after offset) in the 191 * range [x-1, x). 192 * 193 * <ul> 194 * <li> Setting this to 1 makes the absolute position unsigned [0, 195 * 1) 196 * <li> Setting this to 0.5 makes the absolute position signed 197 * [-0.5, 0.5) 198 * <li> Setting this to 0 makes the absolute position always 199 * negative [-1, 0) 200 * </ul> 201 * 202 * Many rotational mechanisms such as arms have a region of motion 203 * that is unreachable. This should be set to the center of that 204 * region of motion, in non-negative rotations. This affects the 205 * position of the device at bootup. 206 * <p> 207 * For example, consider an arm which can travel from -0.2 to 0.6 208 * rotations with a little leeway, where 0 is horizontally forward. 209 * Since -0.2 rotations has the same absolute position as 0.8 210 * rotations, we can say that the arm typically does not travel in the 211 * range (0.6, 0.8) rotations. As a result, the discontinuity point 212 * would be the center of that range, which is 0.7 rotations. This 213 * results in an absolute sensor range of [-0.3, 0.7) rotations. 214 * <p> 215 * Given a total range of motion less than 1 rotation, users can 216 * calculate the discontinuity point using mean(lowerLimit, 217 * upperLimit) + 0.5. If that results in a value outside the range [0, 218 * 1], either cap the value to [0, 1], or add/subtract 1.0 rotation 219 * from your lower and upper limits of motion. 220 * <p> 221 * On a Talon motor controller, this is only supported when using the 222 * PulseWidth sensor source. 223 * 224 * <ul> 225 * <li> <b>Minimum Value:</b> 0.0 226 * <li> <b>Maximum Value:</b> 1.0 227 * <li> <b>Default Value:</b> 0.5 228 * <li> <b>Units:</b> rotations 229 * </ul> 230 * 231 * @param newAbsoluteSensorDiscontinuityPoint Parameter to modify 232 * @return Itself 233 */ 234 public MagnetSensorConfigs withAbsoluteSensorDiscontinuityPoint(double newAbsoluteSensorDiscontinuityPoint) 235 { 236 AbsoluteSensorDiscontinuityPoint = newAbsoluteSensorDiscontinuityPoint; 237 return this; 238 } 239 240 /** 241 * Modifies this configuration's AbsoluteSensorDiscontinuityPoint parameter and returns itself for 242 * method-chaining and easier to use config API. 243 * <p> 244 * The positive discontinuity point of the absolute sensor in 245 * rotations. This determines the point at which the absolute sensor 246 * wraps around, keeping the absolute position (after offset) in the 247 * range [x-1, x). 248 * 249 * <ul> 250 * <li> Setting this to 1 makes the absolute position unsigned [0, 251 * 1) 252 * <li> Setting this to 0.5 makes the absolute position signed 253 * [-0.5, 0.5) 254 * <li> Setting this to 0 makes the absolute position always 255 * negative [-1, 0) 256 * </ul> 257 * 258 * Many rotational mechanisms such as arms have a region of motion 259 * that is unreachable. This should be set to the center of that 260 * region of motion, in non-negative rotations. This affects the 261 * position of the device at bootup. 262 * <p> 263 * For example, consider an arm which can travel from -0.2 to 0.6 264 * rotations with a little leeway, where 0 is horizontally forward. 265 * Since -0.2 rotations has the same absolute position as 0.8 266 * rotations, we can say that the arm typically does not travel in the 267 * range (0.6, 0.8) rotations. As a result, the discontinuity point 268 * would be the center of that range, which is 0.7 rotations. This 269 * results in an absolute sensor range of [-0.3, 0.7) rotations. 270 * <p> 271 * Given a total range of motion less than 1 rotation, users can 272 * calculate the discontinuity point using mean(lowerLimit, 273 * upperLimit) + 0.5. If that results in a value outside the range [0, 274 * 1], either cap the value to [0, 1], or add/subtract 1.0 rotation 275 * from your lower and upper limits of motion. 276 * <p> 277 * On a Talon motor controller, this is only supported when using the 278 * PulseWidth sensor source. 279 * 280 * <ul> 281 * <li> <b>Minimum Value:</b> 0.0 282 * <li> <b>Maximum Value:</b> 1.0 283 * <li> <b>Default Value:</b> 0.5 284 * <li> <b>Units:</b> rotations 285 * </ul> 286 * 287 * @param newAbsoluteSensorDiscontinuityPoint Parameter to modify 288 * @return Itself 289 */ 290 public MagnetSensorConfigs withAbsoluteSensorDiscontinuityPoint(Angle newAbsoluteSensorDiscontinuityPoint) 291 { 292 AbsoluteSensorDiscontinuityPoint = newAbsoluteSensorDiscontinuityPoint.in(Rotations); 293 return this; 294 } 295 296 /** 297 * Helper method to get this configuration's AbsoluteSensorDiscontinuityPoint parameter converted 298 * to a unit type. If not using the Java units library, {@link #AbsoluteSensorDiscontinuityPoint} 299 * can be accessed directly instead. 300 * <p> 301 * The positive discontinuity point of the absolute sensor in 302 * rotations. This determines the point at which the absolute sensor 303 * wraps around, keeping the absolute position (after offset) in the 304 * range [x-1, x). 305 * 306 * <ul> 307 * <li> Setting this to 1 makes the absolute position unsigned [0, 308 * 1) 309 * <li> Setting this to 0.5 makes the absolute position signed 310 * [-0.5, 0.5) 311 * <li> Setting this to 0 makes the absolute position always 312 * negative [-1, 0) 313 * </ul> 314 * 315 * Many rotational mechanisms such as arms have a region of motion 316 * that is unreachable. This should be set to the center of that 317 * region of motion, in non-negative rotations. This affects the 318 * position of the device at bootup. 319 * <p> 320 * For example, consider an arm which can travel from -0.2 to 0.6 321 * rotations with a little leeway, where 0 is horizontally forward. 322 * Since -0.2 rotations has the same absolute position as 0.8 323 * rotations, we can say that the arm typically does not travel in the 324 * range (0.6, 0.8) rotations. As a result, the discontinuity point 325 * would be the center of that range, which is 0.7 rotations. This 326 * results in an absolute sensor range of [-0.3, 0.7) rotations. 327 * <p> 328 * Given a total range of motion less than 1 rotation, users can 329 * calculate the discontinuity point using mean(lowerLimit, 330 * upperLimit) + 0.5. If that results in a value outside the range [0, 331 * 1], either cap the value to [0, 1], or add/subtract 1.0 rotation 332 * from your lower and upper limits of motion. 333 * <p> 334 * On a Talon motor controller, this is only supported when using the 335 * PulseWidth sensor source. 336 * 337 * <ul> 338 * <li> <b>Minimum Value:</b> 0.0 339 * <li> <b>Maximum Value:</b> 1.0 340 * <li> <b>Default Value:</b> 0.5 341 * <li> <b>Units:</b> rotations 342 * </ul> 343 * 344 * @return AbsoluteSensorDiscontinuityPoint 345 */ 346 public Angle getAbsoluteSensorDiscontinuityPointMeasure() 347 { 348 return Rotations.of(AbsoluteSensorDiscontinuityPoint); 349 } 350 351 352 353 @Override 354 public String toString() 355 { 356 String ss = "Config Group: MagnetSensor\n"; 357 ss += " SensorDirection: " + SensorDirection + "\n"; 358 ss += " MagnetOffset: " + MagnetOffset + " rotations" + "\n"; 359 ss += " AbsoluteSensorDiscontinuityPoint: " + AbsoluteSensorDiscontinuityPoint + " rotations" + "\n"; 360 return ss; 361 } 362 363 /** 364 * 365 */ 366 public StatusCode deserialize(String to_deserialize) 367 { 368 SensorDirection = SensorDirectionValue.valueOf(ConfigJNI.Deserializeint(SpnValue.CANcoder_SensorDirection.value, to_deserialize)); 369 MagnetOffset = ConfigJNI.Deserializedouble(SpnValue.CANCoder_MagnetOffset.value, to_deserialize); 370 AbsoluteSensorDiscontinuityPoint = ConfigJNI.Deserializedouble(SpnValue.Config_AbsoluteSensorDiscontinuityPoint.value, to_deserialize); 371 return StatusCode.OK; 372 } 373 374 /** 375 * 376 */ 377 public String serialize() 378 { 379 String ss = ""; 380 ss += ConfigJNI.Serializeint(SpnValue.CANcoder_SensorDirection.value, SensorDirection.value); 381 ss += ConfigJNI.Serializedouble(SpnValue.CANCoder_MagnetOffset.value, MagnetOffset); 382 ss += ConfigJNI.Serializedouble(SpnValue.Config_AbsoluteSensorDiscontinuityPoint.value, AbsoluteSensorDiscontinuityPoint); 383 return ss; 384 } 385} 386