001/* Copyright (C) Cross The Road Electronics 2024 */
002package com.ctre.phoenix.motorcontrol;
003
004import com.ctre.phoenix.ErrorCode;
005import com.ctre.phoenix.ParamEnum;
006import com.ctre.phoenix.motion.MotionProfileStatus;
007import com.ctre.phoenix.motion.TrajectoryPoint;
008import com.ctre.phoenix.motorcontrol.can.BaseTalon;
009import com.ctre.phoenix.sensors.CANCoder;
010
011/**
012 * Interface for motor controllers
013 */
014public interface IMotorController
015                extends com.ctre.phoenix.signals.IOutputSignal, com.ctre.phoenix.signals.IInvertable, IFollower {
016        // ------ Set output routines. ----------//
017        /**
018         * Sets the appropriate output on the talon, depending on the mode.
019         * @param Mode The output mode to apply.
020         * In PercentOutput, the output is between -1.0 and 1.0, with 0.0 as stopped.
021         * In Current mode, output value is in amperes.
022         * In Velocity mode, output value is in position change / 100ms.
023         * In Position mode, output value is in encoder ticks or an analog value,
024         *   depending on the sensor.
025         * In Follower mode, the output value is the integer device ID of the talon to
026         * duplicate.
027         *
028         * @param demand The setpoint value, as described above.
029         *
030         *
031         *      Standard Driving Example:
032         *      _talonLeft.set(ControlMode.PercentOutput, leftJoy);
033         *      _talonRght.set(ControlMode.PercentOutput, rghtJoy);
034         */
035        public void set(ControlMode Mode, double demand);
036
037        /**
038         * @param Mode Sets the appropriate output on the talon, depending on the mode.
039         * @param demand0 The output value to apply.
040         *      such as advanced feed forward and/or auxiliary close-looping in firmware.
041         * In PercentOutput, the output is between -1.0 and 1.0, with 0.0 as stopped.
042         * In Current mode, output value is in amperes.
043         * In Velocity mode, output value is in position change / 100ms.
044         * In Position mode, output value is in encoder ticks or an analog value,
045         *   depending on the sensor. See
046         * In Follower mode, the output value is the integer device ID of the talon to
047         * duplicate.
048         *
049         * @param demand1Type The demand type for demand1.
050         * Neutral: Ignore demand1 and apply no change to the demand0 output.
051         * AuxPID: Use demand1 to set the target for the auxiliary PID 1.
052         * ArbitraryFeedForward: Use demand1 as an arbitrary additive value to the
053         *       demand0 output.  In PercentOutput the demand0 output is the motor output,
054         *   and in closed-loop modes the demand0 output is the output of PID0.
055         * @param demand1 Supplmental output value.  Units match the set mode.
056         *
057         *
058         *  Arcade Drive Example:
059         *              _talonLeft.set(ControlMode.PercentOutput, joyForward, DemandType.ArbitraryFeedForward, +joyTurn);
060         *              _talonRght.set(ControlMode.PercentOutput, joyForward, DemandType.ArbitraryFeedForward, -joyTurn);
061         *
062         *      Drive Straight Example:
063         *      Note: Selected Sensor Configuration is necessary for both PID0 and PID1.
064         *              _talonLeft.follow(_talonRght, FollwerType.AuxOutput1);
065         *              _talonRght.set(ControlMode.PercentOutput, joyForward, DemandType.AuxPID, desiredRobotHeading);
066         *
067         *      Drive Straight to a Distance Example:
068         *      Note: Other configurations (sensor selection, PID gains, etc.) need to be set.
069         *              _talonLeft.follow(_talonRght, FollwerType.AuxOutput1);
070         *              _talonRght.set(ControlMode.MotionMagic, targetDistance, DemandType.AuxPID, desiredRobotHeading);
071         */
072        public void set(ControlMode Mode, double demand0, DemandType demand1Type, double demand1);
073
074        /**
075         * Neutral the motor output by setting control mode to disabled.
076         */
077        public void neutralOutput();
078
079        /**
080         * Sets the mode of operation during neutral throttle output.
081         *
082         * @param neutralMode
083         *            The desired mode of operation when the Controller output
084         *            throttle is neutral (ie brake/coast)
085         **/
086        public void setNeutralMode(NeutralMode neutralMode);
087
088        // ------ Invert behavior ----------//
089        /**
090         * Sets the phase of the sensor. Use when controller forward/reverse output
091         * doesn't correlate to appropriate forward/reverse reading of sensor.
092         * Pick a value so that positive PercentOutput yields a positive change in sensor.
093         * After setting this, user can freely call SetInverted() with any value.
094         *
095         * @param PhaseSensor
096         *            Indicates whether to invert the phase of the sensor.
097         */
098        public void setSensorPhase(boolean PhaseSensor);
099
100        /**
101         * Inverts the hbridge output of the motor controller.
102         *
103         * This does not impact sensor phase and should not be used to correct sensor polarity.
104         *
105         * This will invert the hbridge output but NOT the LEDs.
106         * This ensures....
107         *  - Green LEDs always represents positive request from robot-controller/closed-looping mode.
108         *  - Green LEDs correlates to forward limit switch.
109         *  - Green LEDs correlates to forward soft limit.
110         *
111         * @param invert
112         *            Invert state to set.
113         */
114        public void setInverted(boolean invert);
115
116        /**
117         * Inverts the hbridge output of the motor controller in relation to the master if present 
118         *
119         * This does not impact sensor phase and should not be used to correct sensor polarity.
120         *
121         * This will allow you to either:
122         *  - Not invert the motor
123         *  - Invert the motor
124         *  - Always follow the master regardless of master's inversion
125         *  - Always oppose the master regardless of master's inversion
126         *
127         * @param invertType
128         *            Invert state to set.
129         */
130        public void setInverted(InvertType invertType);
131
132        /**
133         * @return invert setting of motor output.
134         */
135        public boolean getInverted();
136
137        // ----- general output shaping ------------------//
138        /**
139         * Configures the open-loop ramp rate of throttle output.
140         *
141         * @param secondsFromNeutralToFull
142         *            Minimum desired time to go from neutral to full throttle. A
143         *            value of '0' will disable the ramp.
144         * @param timeoutMs
145         *            Timeout value in ms. If nonzero, function will wait for
146         *            config success and report an error if it times out.
147         *            If zero, no blocking or checking is performed.
148         * @return Error Code generated by function. 0 indicates no error.
149         */
150        public ErrorCode configOpenloopRamp(double secondsFromNeutralToFull, int timeoutMs);
151
152        /**
153         * Configures the closed-loop ramp rate of throttle output.
154         *
155         * @param secondsFromNeutralToFull
156         *            Minimum desired time to go from neutral to full throttle. A
157         *            value of '0' will disable the ramp.
158         * @param timeoutMs
159         *            Timeout value in ms. If nonzero, function will wait for
160         *            config success and report an error if it times out.
161         *            If zero, no blocking or checking is performed.
162         * @return Error Code generated by function. 0 indicates no error.
163         */
164        public ErrorCode configClosedloopRamp(double secondsFromNeutralToFull, int timeoutMs);
165
166        /**
167         * Configures the forward peak output percentage.
168         *
169         * @param percentOut
170         *            Desired peak output percentage. [0,1]
171         * @param timeoutMs
172         *            Timeout value in ms. If nonzero, function will wait for
173         *            config success and report an error if it times out.
174         *            If zero, no blocking or checking is performed.
175         * @return Error Code generated by function. 0 indicates no error.
176         */
177        public ErrorCode configPeakOutputForward(double percentOut, int timeoutMs);
178
179        /**
180         * Configures the reverse peak output percentage.
181         *
182         * @param percentOut
183         *            Desired peak output percentage.
184         * @param timeoutMs
185         *            Timeout value in ms. If nonzero, function will wait for
186         *            config success and report an error if it times out.
187         *            If zero, no blocking or checking is performed.
188         * @return Error Code generated by function. 0 indicates no error.
189         */
190        public ErrorCode configPeakOutputReverse(double percentOut, int timeoutMs);
191
192        /**
193         * Configures the forward nominal output percentage.
194         *
195         * @param percentOut
196         *            Nominal (minimum) percent output. [0,+1]
197         * @param timeoutMs
198         *            Timeout value in ms. If nonzero, function will wait for
199         *            config success and report an error if it times out.
200         *            If zero, no blocking or checking is performed.
201         * @return Error Code generated by function. 0 indicates no error.
202         */
203        public ErrorCode configNominalOutputForward(double percentOut, int timeoutMs);
204
205        /**
206         * Configures the reverse nominal output percentage.
207         *
208         * @param percentOut
209         *            Nominal (minimum) percent output. [-1,0]
210         * @param timeoutMs
211         *            Timeout value in ms. If nonzero, function will wait for
212         *            config success and report an error if it times out.
213         *            If zero, no blocking or checking is performed.
214         * @return Error Code generated by function. 0 indicates no error.
215         */
216        public ErrorCode configNominalOutputReverse(double percentOut, int timeoutMs);
217
218        /**
219         * Configures the output deadband percentage.
220         *
221         * @param percentDeadband
222         *            Desired deadband percentage. Minimum is 0.1%, Maximum is 25%.
223         *            Pass 0.04 for 4% (factory default).
224         * @param timeoutMs
225         *            Timeout value in ms. If nonzero, function will wait for
226         *            config success and report an error if it times out.
227         *            If zero, no blocking or checking is performed.
228         * @return Error Code generated by function. 0 indicates no error.
229         */
230        public ErrorCode configNeutralDeadband(double percentDeadband, int timeoutMs);
231
232        // ------ Voltage Compensation ----------//
233        /**
234         * Configures the Voltage Compensation saturation voltage.
235         *
236         * @param voltage
237         *            This is the max voltage to apply to the hbridge when voltage
238         *            compensation is enabled.  For example, if 10 (volts) is specified
239         *            and a TalonSRX is commanded to 0.5 (PercentOutput, closed-loop, etc)
240         *            then the TalonSRX will attempt to apply a duty-cycle to produce 5V.
241         * @param timeoutMs
242         *            Timeout value in ms. If nonzero, function will wait for
243         *            config success and report an error if it times out.
244         *            If zero, no blocking or checking is performed.
245         * @return Error Code generated by function. 0 indicates no error.
246         */
247        public ErrorCode configVoltageCompSaturation(double voltage, int timeoutMs);
248
249        /**
250         * Configures the voltage measurement filter.
251         *
252         * @param filterWindowSamples
253         *            Number of samples in the rolling average of voltage
254         *            measurement.
255         * @param timeoutMs
256         *            Timeout value in ms. If nonzero, function will wait for
257         *            config success and report an error if it times out.
258         *            If zero, no blocking or checking is performed.
259         * @return Error Code generated by function. 0 indicates no error.
260         */
261        public ErrorCode configVoltageMeasurementFilter(int filterWindowSamples, int timeoutMs);
262
263        /**
264         * Enables voltage compensation. If enabled, voltage compensation works in
265         * all control modes.  
266         * 
267         * Be sure to configure the saturation voltage before enabling this.
268         *
269         * @param enable
270         *            Enable state of voltage compensation.
271         **/
272        public void enableVoltageCompensation(boolean enable);
273
274        // ------ General Status ----------//
275        
276        /**
277         * Gets the bus voltage seen by the device.
278         *
279         * @return The bus voltage value (in volts).
280         */
281        public double getBusVoltage() ;
282
283        /**
284         * Gets the output percentage of the motor controller.
285         *
286         * @return Output of the motor controller (in percent).
287         */
288        public double getMotorOutputPercent() ;
289
290        /**
291         * @return applied voltage to motor  in volts.
292         */
293        public double getMotorOutputVoltage() ;
294
295        /**
296         * Gets the temperature of the motor controller.
297         *
298         * @return Temperature of the motor controller (in 'C)
299         */
300        public double getTemperature() ;
301
302        // ------ sensor selection ----------//
303        /**
304         * Select the remote feedback device for the motor controller.
305         * Most CTRE CAN motor controllers will support remote sensors over CAN.
306         *
307         * @param feedbackDevice
308         *            Remote Feedback Device to select.
309         * @param pidIdx
310         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
311         * @param timeoutMs
312         *            Timeout value in ms. If nonzero, function will wait for
313         *            config success and report an error if it times out.
314         *            If zero, no blocking or checking is performed.
315         * @return Error Code generated by function. 0 indicates no error.
316         */
317        public ErrorCode configSelectedFeedbackSensor(RemoteFeedbackDevice feedbackDevice, int pidIdx, int timeoutMs);
318
319        /**
320         * The Feedback Coefficient is a scalar applied to the value of the
321         * feedback sensor.  Useful when you need to scale your sensor values
322         * within the closed-loop calculations.  Default value is 1.
323         *
324         * Selected Feedback Sensor register in firmware is the decoded sensor value
325         * multiplied by the Feedback Coefficient.
326         *
327         * @param coefficient
328         *            Feedback Coefficient value.  Maximum value of 1.
329         *                                              Resolution is 1/(2^16).  Cannot be 0.
330         * @param pidIdx
331         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
332         * @param timeoutMs
333         *            Timeout value in ms. If nonzero, function will wait for
334         *            config success and report an error if it times out.
335         *            If zero, no blocking or checking is performed.
336         * @return Error Code generated by function. 0 indicates no error.
337         */
338        public ErrorCode configSelectedFeedbackCoefficient(double coefficient, int pidIdx, int timeoutMs);
339
340        /**
341         * Select what remote device and signal to assign to Remote Sensor 0 or Remote Sensor 1.
342         * After binding a remote device and signal to Remote Sensor X, you may select Remote Sensor X
343         * as a PID source for closed-loop features.
344         *
345         * @param deviceID
346         *            The device ID of the remote sensor device.
347         * @param remoteSensorSource
348         *            The remote sensor device and signal type to bind.
349         * @param remoteOrdinal
350         *            0 for configuring Remote Sensor 0,
351         *            1 for configuring Remote Sensor 1
352         * @param timeoutMs
353         *            Timeout value in ms. If nonzero, function will wait for
354         *            config success and report an error if it times out.
355         *            If zero, no blocking or checking is performed.
356         * @return Error Code generated by function. 0 indicates no error.
357         */
358        public ErrorCode configRemoteFeedbackFilter(int deviceID, RemoteSensorSource remoteSensorSource, int remoteOrdinal,
359                        int timeoutMs);
360
361        /**
362         * Select what remote device and signal to assign to Remote Sensor 0 or Remote Sensor 1.
363         * After binding a remote device and signal to Remote Sensor X, you may select Remote Sensor X
364         * as a PID source for closed-loop features.
365         *
366         * @param canCoderRef
367         *            CANCoder device reference to use.
368         * @param remoteOrdinal
369         *            0 for configuring Remote Sensor 0,
370         *            1 for configuring Remote Sensor 1
371         * @param timeoutMs
372         *            Timeout value in ms. If nonzero, function will wait for
373         *            config success and report an error if it times out.
374         *            If zero, no blocking or checking is performed.
375         * @return Error Code generated by function. 0 indicates no error.
376         */
377        public ErrorCode configRemoteFeedbackFilter(CANCoder canCoderRef, int remoteOrdinal,
378                        int timeoutMs);
379
380        /**
381         * Select what remote device and signal to assign to Remote Sensor 0 or Remote Sensor 1.
382         * After binding a remote device and signal to Remote Sensor X, you may select Remote Sensor X
383         * as a PID source for closed-loop features.
384         *
385         * @param talonRef
386         *            Talon device reference to use.
387         * @param remoteOrdinal
388         *            0 for configuring Remote Sensor 0,
389         *            1 for configuring Remote Sensor 1
390         * @param timeoutMs
391         *            Timeout value in ms. If nonzero, function will wait for
392         *            config success and report an error if it times out.
393         *            If zero, no blocking or checking is performed.
394         * @return Error Code generated by function. 0 indicates no error.
395         */
396        public ErrorCode configRemoteFeedbackFilter(BaseTalon talonRef, int remoteOrdinal,
397                        int timeoutMs);
398
399        /**
400         * Select what sensor term should be bound to switch feedback device.
401         * Sensor Sum = Sensor Sum Term 0 - Sensor Sum Term 1
402         * Sensor Difference = Sensor Diff Term 0 - Sensor Diff Term 1
403         * The four terms are specified with this routine.  Then Sensor Sum/Difference
404         * can be selected for closed-looping.
405         *
406         * @param sensorTerm Which sensor term to bind to a feedback source.
407         * @param feedbackDevice The sensor signal to attach to sensorTerm.
408         * @param timeoutMs
409         *            Timeout value in ms. If nonzero, function will wait for
410         *            config success and report an error if it times out.
411         *            If zero, no blocking or checking is performed.
412         * @return Error Code generated by function. 0 indicates no error.
413         */
414        public ErrorCode configSensorTerm(SensorTerm sensorTerm, FeedbackDevice feedbackDevice, int timeoutMs);
415
416        // ------- sensor status --------- //
417        /**
418         * Get the selected sensor position (in raw sensor units).
419         *
420         * @param pidIdx
421         *            0 for Primary closed-loop. 1 for auxiliary closed-loop. See
422         *            Phoenix-Documentation for how to interpret.
423         *
424         * @return Position of selected sensor (in raw sensor units).
425         */
426        public double getSelectedSensorPosition(int pidIdx);
427
428        /**
429         * Get the selected sensor velocity.
430         *
431         * @param pidIdx
432         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
433         * @return selected sensor (in raw sensor units) per 100ms.
434         * See Phoenix-Documentation for how to interpret.
435         */
436        public double getSelectedSensorVelocity(int pidIdx);
437
438        /**
439         * Sets the sensor position to the given value.
440         *
441         * @param sensorPos
442         *            Position to set for the selected sensor (in raw sensor units).
443         * @param pidIdx
444         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
445         * @param timeoutMs
446         *            Timeout value in ms. If nonzero, function will wait for
447         *            config success and report an error if it times out.
448         *            If zero, no blocking or checking is performed.
449         * @return Error Code generated by function. 0 indicates no error.
450         */
451        public ErrorCode setSelectedSensorPosition(double sensorPos, int pidIdx, int timeoutMs);
452
453        // ------ status frame period changes ----------//
454        /**
455         * Sets the period of the given control frame.
456         *
457         * @param frame
458         *            Frame whose period is to be changed.
459         * @param periodMs
460         *            Period in ms for the given frame.
461         * @return Error Code generated by function. 0 indicates no error.
462         */
463        public ErrorCode setControlFramePeriod(ControlFrame frame, int periodMs);
464
465        /**
466         * Sets the period of the given status frame.
467         *
468         * User ensure CAN Bus utilization is not high.
469         *
470         * This setting is not persistent and is lost when device is reset. If this
471         * is a concern, calling application can use hasResetOccurred() to determine if the
472         * status frame needs to be reconfigured.
473         *
474         * @param frame
475         *            Frame whose period is to be changed.
476         * @param periodMs
477         *            Period in ms for the given frame.
478         * @param timeoutMs
479         *            Timeout value in ms. If nonzero, function will wait for config
480         *            success and report an error if it times out. If zero, no
481         *            blocking or checking is performed.
482         * @return Error Code generated by function. 0 indicates no error.
483         */
484        public ErrorCode setStatusFramePeriod(StatusFrame frame, int periodMs, int timeoutMs);
485
486        /**
487         * Gets the period of the given status frame.
488         *
489         * @param frame
490         *            Frame to get the period of.
491         * @param timeoutMs
492         *            Timeout value in ms. If nonzero, function will wait for
493         *            config success and report an error if it times out.
494         *            If zero, no blocking or checking is performed.
495         * @return Period of the given status frame.
496         */
497        public int getStatusFramePeriod(StatusFrame frame, int timeoutMs);
498
499        //----- velocity signal conditionaing ------//
500        /* not supported */
501
502        //------ remote limit switch ----------//
503        /**
504         * Configures the forward limit switch for a remote source. For example, a
505         * CAN motor controller may need to monitor the Limit-F pin of another Talon
506         * or CANifier.
507         *
508         * @param type
509         *            Remote limit switch source. User can choose between a remote
510         *            Talon SRX, CANifier, or deactivate the feature.
511         * @param normalOpenOrClose
512         *            Setting for normally open, normally closed, or disabled. This
513         *            setting matches the Phoenix Tuner drop down.
514         * @param deviceID
515         *            Device ID of remote source (Talon SRX or CANifier device ID).
516         * @param timeoutMs
517         *            Timeout value in ms. If nonzero, function will wait for config
518         *            success and report an error if it times out. If zero, no
519         *            blocking or checking is performed.
520         * @return Error Code generated by function. 0 indicates no error.
521         */
522        public ErrorCode configForwardLimitSwitchSource(RemoteLimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
523                        int deviceID, int timeoutMs);
524
525        /**
526         * Configures the reverse limit switch for a remote source. For example, a
527         * CAN motor controller may need to monitor the Limit-R pin of another Talon
528         * or CANifier.
529         *
530         * @param type
531         *            Remote limit switch source. User can choose between a remote
532         *            Talon SRX, CANifier, or deactivate the feature.
533         * @param normalOpenOrClose
534         *            Setting for normally open, normally closed, or disabled. This
535         *            setting matches the Phoenix Tuner drop down.
536         * @param deviceID
537         *            Device ID of remote source (Talon SRX or CANifier device ID).
538         * @param timeoutMs
539         *            Timeout value in ms. If nonzero, function will wait for config
540         *            success and report an error if it times out. If zero, no
541         *            blocking or checking is performed.
542         * @return Error Code generated by function. 0 indicates no error.
543         */
544        public ErrorCode configReverseLimitSwitchSource(RemoteLimitSwitchSource type, LimitSwitchNormal normalOpenOrClose,
545                        int deviceID, int timeoutMs);
546
547        /**
548         * Sets the enable state for limit switches.
549         *
550         * @param enable
551         *            Enable state for limit switches.
552         **/
553        public void overrideLimitSwitchesEnable(boolean enable);
554
555        // ------ local limit switch ----------//
556        /* not supported */
557
558        // ------ soft limit ----------//
559        /**
560         * Configures the forward soft limit threhold.
561         *
562         * @param forwardSensorLimit
563         *            Forward Sensor Position Limit (in raw sensor units).
564         * @param timeoutMs
565         *            Timeout value in ms. If nonzero, function will wait for
566         *            config success and report an error if it times out.
567         *            If zero, no blocking or checking is performed.
568         * @return Error Code generated by function. 0 indicates no error.
569         */
570        public ErrorCode configForwardSoftLimitThreshold(double forwardSensorLimit, int timeoutMs);
571
572        /**
573         * Configures the reverse soft limit threshold.
574         *
575         * @param reverseSensorLimit
576         *            Reverse Sensor Position Limit (in raw sensor units).
577         * @param timeoutMs
578         *            Timeout value in ms. If nonzero, function will wait for
579         *            config success and report an error if it times out.
580         *            If zero, no blocking or checking is performed.
581         * @return Error Code generated by function. 0 indicates no error.
582         */
583        public ErrorCode configReverseSoftLimitThreshold(double reverseSensorLimit, int timeoutMs);
584
585        /**
586         * Configures the forward soft limit enable.
587         *
588         * @param enable
589         *            Forward Sensor Position Limit Enable.
590         * @param timeoutMs
591         *            Timeout value in ms. If nonzero, function will wait for
592         *            config success and report an error if it times out.
593         *            If zero, no blocking or checking is performed.
594         * @return Error Code generated by function. 0 indicates no error.
595         */
596        public ErrorCode configForwardSoftLimitEnable(boolean enable, int timeoutMs);
597
598        /**
599         * Configures the reverse soft limit enable.
600         *
601         * @param enable
602         *            Reverse Sensor Position Limit Enable.
603         * @param timeoutMs
604         *            Timeout value in ms. If nonzero, function will wait for config
605         *            success and report an error if it times out. If zero, no
606         *            blocking or checking is performed.
607         * @return Error Code generated by function. 0 indicates no error.
608         */
609        public ErrorCode configReverseSoftLimitEnable(boolean enable, int timeoutMs);
610
611        /**
612         * Can be used to override-disable the soft limits.
613         * This function can be used to quickly disable soft limits without
614         * having to modify the persistent configuration.
615         *
616         * @param enable
617         *            Enable state for soft limit switches.
618         */
619        public void overrideSoftLimitsEnable(boolean enable);
620
621        // ------ Current Lim ----------//
622        /* not supported */
623
624        // ------ General Close loop ----------//
625        /**
626         * Sets the 'P' constant in the given parameter slot.
627         * This is multiplied by closed loop error in sensor units.  
628         * Note the closed loop output interprets a final value of 1023 as full output.  
629         * So use a gain of '0.25' to get full output if err is 4096u (Mag Encoder 1 rotation)
630         *
631         * @param slotIdx
632         *            Parameter slot for the constant.
633         * @param value
634         *            Value of the P constant.
635         * @param timeoutMs
636         *            Timeout value in ms. If nonzero, function will wait for
637         *            config success and report an error if it times out.
638         *            If zero, no blocking or checking is performed.
639         * @return Error Code generated by function. 0 indicates no error.
640         */
641        public ErrorCode config_kP(int slotIdx, double value, int timeoutMs);
642
643        /**
644         * Sets the 'I' constant in the given parameter slot.
645         * This is multiplied by accumulated closed loop error in sensor units every PID Loop.  
646         * Note the closed loop output interprets a final value of 1023 as full output.  
647         * So use a gain of '0.00025' to get full output if err is 4096u for 1000 loops (accumulater holds 4,096,000),
648         * [which is equivalent to one CTRE mag encoder rotation for 1000 milliseconds].
649         *
650         * @param slotIdx
651         *            Parameter slot for the constant.
652         * @param value
653         *            Value of the I constant.
654         * @param timeoutMs
655         *            Timeout value in ms. If nonzero, function will wait for
656         *            config success and report an error if it times out.
657         *            If zero, no blocking or checking is performed.
658         * @return Error Code generated by function. 0 indicates no error.
659         */
660        public ErrorCode config_kI(int slotIdx, double value, int timeoutMs);
661
662        /**
663         * Sets the 'D' constant in the given parameter slot.
664         *
665         * This is multiplied by derivative error (sensor units per PID loop, typically 1ms).  
666         * Note the closed loop output interprets a final value of 1023 as full output.  
667         * So use a gain of '250' to get full output if derr is 4096u (Mag Encoder 1 rotation) per 1000 loops (typ 1 sec)
668         *
669         * @param slotIdx
670         *            Parameter slot for the constant.
671         * @param value
672         *            Value of the D constant.
673         * @param timeoutMs
674         *            Timeout value in ms. If nonzero, function will wait for
675         *            config success and report an error if it times out.
676         *            If zero, no blocking or checking is performed.
677         * @return Error Code generated by function. 0 indicates no error.
678         */
679        public ErrorCode config_kD(int slotIdx, double value, int timeoutMs);
680
681        /**
682         * Sets the 'F' constant in the given parameter slot.
683         *
684         * See documentation for calculation details.  
685         * If using velocity, motion magic, or motion profile, 
686         * use (1023 * duty-cycle / sensor-velocity-sensor-units-per-100ms).
687         *
688         * @param slotIdx
689         *            Parameter slot for the constant.
690         * @param value
691         *            Value of the F constant.
692         * @param timeoutMs
693         *            Timeout value in ms. If nonzero, function will wait for
694         *            config success and report an error if it times out.
695         *            If zero, no blocking or checking is performed.
696         * @return Error Code generated by function. 0 indicates no error.
697         */
698        public ErrorCode config_kF(int slotIdx, double value, int timeoutMs);
699
700        /**
701         * Sets the Integral Zone constant in the given parameter slot. If the
702         * (absolute) closed-loop error is outside of this zone, integral
703         * accumulator is automatically cleared. This ensures than integral wind up
704         * events will stop after the sensor gets far enough from its target.
705         *
706         * @param slotIdx
707         *            Parameter slot for the constant.
708         * @param izone
709         *            Value of the Integral Zone constant (closed loop error units X
710         *            1ms).
711         * @param timeoutMs
712         *            Timeout value in ms. If nonzero, function will wait for config
713         *            success and report an error if it times out. If zero, no
714         *            blocking or checking is performed.
715         * @return Error Code generated by function. 0 indicates no error.
716         */
717        public ErrorCode config_IntegralZone(int slotIdx, double izone, int timeoutMs);
718
719        /**
720         * Sets the allowable closed-loop error in the given parameter slot.
721         *
722         * @param slotIdx
723         *            Parameter slot for the constant.
724         * @param allowableCloseLoopError
725         *            Value of the allowable closed-loop error in sensor units (or sensor units per 100ms for velocity).
726         * @param timeoutMs
727         *            Timeout value in ms. If nonzero, function will wait for
728         *            config success and report an error if it times out.
729         *            If zero, no blocking or checking is performed.
730         * @return Error Code generated by function. 0 indicates no error.
731         */
732        public ErrorCode configAllowableClosedloopError(int slotIdx, double allowableCloseLoopError, int timeoutMs);
733
734        /**
735         * Sets the maximum integral accumulator in the given parameter slot.
736         *
737         * @param slotIdx
738         *            Parameter slot for the constant.
739         * @param iaccum
740         *            Value of the maximum integral accumulator (closed loop error
741         *            units X 1ms).
742         * @param timeoutMs
743         *            Timeout value in ms. If nonzero, function will wait for config
744         *            success and report an error if it times out. If zero, no
745         *            blocking or checking is performed.
746         * @return Error Code generated by function. 0 indicates no error.
747         */
748        public ErrorCode configMaxIntegralAccumulator(int slotIdx, double iaccum, int timeoutMs);
749
750        /**
751         * Sets the peak closed-loop output.  This peak output is slot-specific and
752         *   is applied to the output of the associated PID loop.
753         * This setting is seperate from the generic Peak Output setting.
754         *
755         * @param slotIdx
756         *            Parameter slot for the constant.
757         * @param percentOut
758         *            Peak Percent Output from 0 to 1.  This value is absolute and
759         *                                              the magnitude will apply in both forward and reverse directions.
760         * @param timeoutMs
761         *            Timeout value in ms. If nonzero, function will wait for
762         *            config success and report an error if it times out.
763         *            If zero, no blocking or checking is performed.
764         * @return Error Code generated by function. 0 indicates no error.
765         */
766        public ErrorCode configClosedLoopPeakOutput(int slotIdx, double percentOut, int timeoutMs);
767
768        /**
769         * Sets the loop time (in milliseconds) of the PID closed-loop calculations.
770         * Default value is 1 ms.
771         *
772         * @param slotIdx
773         *            Parameter slot for the constant.
774         * @param loopTimeMs
775         *            Loop timing of the closed-loop calculations.  Minimum value of
776         *                                              1 ms, maximum of 64 ms.
777         * @param timeoutMs
778         *            Timeout value in ms. If nonzero, function will wait for
779         *            config success and report an error if it times out.
780         *            If zero, no blocking or checking is performed.
781         * @return Error Code generated by function. 0 indicates no error.
782         */
783        public ErrorCode configClosedLoopPeriod(int slotIdx, int loopTimeMs, int timeoutMs);
784
785        /**
786         * Configures the Polarity of the Auxiliary PID (PID1).
787         *
788         * Standard Polarity:
789         *    Primary Output = PID0 + PID1,
790         *    Auxiliary Output = PID0 - PID1,
791         *
792         * Inverted Polarity:
793         *    Primary Output = PID0 - PID1,
794         *    Auxiliary Output = PID0 + PID1,
795         *
796         * @param invert
797         *            If true, use inverted PID1 output polarity.
798         * @param timeoutMs
799         *            Timeout value in ms. If nonzero, function will wait for config
800         *            success and report an error if it times out. If zero, no
801         *            blocking or checking is performed.
802         * @return Error Code
803         */
804        public ErrorCode configAuxPIDPolarity(boolean invert, int timeoutMs);
805
806        //------ Close loop State ----------//
807        /**
808         * Sets the integral accumulator. Typically this is used to clear/zero the
809         * integral accumulator, however some use cases may require seeding the
810         * accumulator for a faster response.
811         *
812         * @param iaccum
813         *            Value to set for the integral accumulator (closed loop error
814         *            units X 1ms).
815         * @param pidIdx
816         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
817         * @param timeoutMs
818         *            Timeout value in ms. If nonzero, function will wait for config
819         *            success and report an error if it times out. If zero, no
820         *            blocking or checking is performed.
821         * @return Error Code generated by function. 0 indicates no error.
822         */
823        public ErrorCode setIntegralAccumulator(double iaccum, int pidIdx, int timeoutMs);
824
825        /**
826         * Gets the closed-loop error. The units depend on which control mode is in
827         * use. 
828         *
829         * If closed-loop is seeking a target sensor position, closed-loop error is the difference between target 
830         * and current sensor value (in sensor units.  Example 4096 units per rotation for CTRE Mag Encoder).
831         *
832         * If closed-loop is seeking a target sensor velocity, closed-loop error is the difference between target 
833         * and current sensor value (in sensor units per 100ms).
834         *
835         * If using motion profiling or Motion Magic, closed loop error is calculated against the current target,
836         * and not the "final" target at the end of the profile/movement.
837         *
838         * See Phoenix-Documentation information on units.
839         *
840         * @param pidIdx
841         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
842         * @return Closed-loop error value.
843         */
844        public double getClosedLoopError(int pidIdx);
845
846        /**
847         * Gets the iaccum value.
848         *
849         * @param pidIdx
850         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
851         * @return Integral accumulator value (Closed-loop error X 1ms).
852         */
853        public double getIntegralAccumulator(int pidIdx) ;
854
855        /**
856         * Gets the derivative of the closed-loop error.
857         *
858         * @param pidIdx
859         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
860         * @return The error derivative value.
861         */
862        public double getErrorDerivative(int pidIdx) ;
863
864        /**
865         * Selects which profile slot to use for closed-loop control.
866         *
867         * @param slotIdx
868         *            Profile slot to select.
869         * @param pidIdx
870         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
871         **/
872        public void selectProfileSlot(int slotIdx, int pidIdx);
873
874        /**
875         * Gets the current target of a given closed loop.
876         *
877         * @param pidIdx
878         *            0 for Primary closed-loop. 1 for auxiliary closed-loop.
879         * @return The closed loop target.
880         */
881        public double getClosedLoopTarget(int pidIdx); // will be added to JNI
882
883        /**
884         * Gets the active trajectory target position for pid0 using
885         * MotionMagic/MotionProfile control modes.
886         *
887         * @return The Active Trajectory Position in sensor units.
888         */
889        public double getActiveTrajectoryPosition();
890
891        /**
892         * Gets the active trajectory target velocity for pid0 using
893         * MotionMagic/MotionProfile control modes.
894         *
895         * @return The Active Trajectory Velocity in sensor units per 100ms.
896         */
897        public double getActiveTrajectoryVelocity();
898
899        // ------ Motion Profile Settings used in Motion Magic and Motion Profile
900        /**
901         * Sets the Motion Magic Cruise Velocity. This is the peak target velocity
902         * that the motion magic curve generator can use.
903         *
904         * @param sensorUnitsPer100ms
905         *            Motion Magic Cruise Velocity (in raw sensor units per 100 ms).
906         * @param timeoutMs
907         *            Timeout value in ms. If nonzero, function will wait for config
908         *            success and report an error if it times out. If zero, no
909         *            blocking or checking is performed.
910         * @return Error Code generated by function. 0 indicates no error.
911         */
912        public ErrorCode configMotionCruiseVelocity(double sensorUnitsPer100ms, int timeoutMs);
913
914        /**
915         * Sets the Motion Magic Acceleration. This is the target acceleration that
916         * the motion magic curve generator can use.
917         *
918         * @param sensorUnitsPer100msPerSec
919         *            Motion Magic Acceleration (in raw sensor units per 100 ms per
920         *            second).
921         * @param timeoutMs
922         *            Timeout value in ms. If nonzero, function will wait for config
923         *            success and report an error if it times out. If zero, no
924         *            blocking or checking is performed.
925         * @return Error Code generated by function. 0 indicates no error.
926         */
927        public ErrorCode configMotionAcceleration(double sensorUnitsPer100msPerSec, int timeoutMs);
928
929        /**
930         * Sets the Motion Magic S Curve Strength.
931         * Call this before using Motion Magic.
932         * Modifying this during a Motion Magic action should be avoided.
933         *
934         * @param curveStrength
935         *            0 to use Trapezoidal Motion Profile. [1,8] for S-Curve (greater value yields greater smoothing).
936         * @param timeoutMs
937         *            Timeout value in ms. If nonzero, function will wait for config
938         *            success and report an error if it times out. If zero, no
939         *            blocking or checking is performed.
940         * @return Error Code generated by function. 0 indicates no error.
941         */
942        public ErrorCode configMotionSCurveStrength(int curveStrength, int timeoutMs);
943        
944        /**
945         * When trajectory points are processed in the motion profile executer, the MPE determines
946         * how long to apply the active trajectory point by summing baseTrajDurationMs with the
947         * timeDur of the trajectory point (see TrajectoryPoint).
948         *
949         * This allows general selection of the execution rate of the points with 1ms resolution,
950         * while allowing some degree of change from point to point.
951         * @param baseTrajDurationMs The base duration time of every trajectory point.
952         *                                                      This is summed with the trajectory points unique timeDur.
953         * @param timeoutMs
954         *            Timeout value in ms. If nonzero, function will wait for
955         *            config success and report an error if it times out.
956         *            If zero, no blocking or checking is performed.
957         * @return Error Code generated by function. 0 indicates no error.
958         */
959        public ErrorCode configMotionProfileTrajectoryPeriod(int baseTrajDurationMs, int timeoutMs);
960
961        // ------ Motion Profile Buffer ----------//
962        /**
963         * Clear the buffered motion profile in both controller's RAM (bottom), and in the
964         * API (top).
965         * 
966         * @return Error Code generated by function. 0 indicates no error
967         */
968        public ErrorCode clearMotionProfileTrajectories();
969        /**
970         * Retrieve just the buffer count for the api-level (top) buffer. This
971         * routine performs no CAN or data structure lookups, so its fast and ideal
972         * if caller needs to quickly poll the progress of trajectory points being
973         * emptied into controller's RAM. Otherwise just use GetMotionProfileStatus.
974         *
975         * @return number of trajectory points in the top buffer.
976         */
977        public int getMotionProfileTopLevelBufferCount();
978        /**
979         * Push another trajectory point into the top level buffer (which is emptied
980         * into the motor controller's bottom buffer as room allows).
981         * @param trajPt to push into buffer.
982         * The members should be filled in with these values...
983         *
984         *              targPos:  servo position in sensor units.
985         *              targVel:  velocity to feed-forward in sensor units
986         *                 per 100ms.
987         *              profileSlotSelect0  Which slot to get PIDF gains. PID is used for position servo. F is used
988         *                                                 as the Kv constant for velocity feed-forward. Typically this is hardcoded
989         *                                                 to the a particular slot, but you are free gain schedule if need be.
990         *                                                 Choose from [0,3]
991         *              profileSlotSelect1 Which slot to get PIDF gains for auxiliary PId.
992         *                                                 This only has impact during MotionProfileArc Control mode.
993         *                                                 Choose from [0,1].
994         *         isLastPoint  set to nonzero to signal motor controller to keep processing this
995         *                     trajectory point, instead of jumping to the next one
996         *                     when timeDurMs expires.  Otherwise MP executer will
997         *                     eventually see an empty buffer after the last point
998         *                     expires, causing it to assert the IsUnderRun flag.
999         *                     However this may be desired if calling application
1000         *                     never wants to terminate the MP.
1001         *              zeroPos  set to nonzero to signal motor controller to "zero" the selected
1002         *                 position sensor before executing this trajectory point.
1003         *                 Typically the first point should have this set only thus
1004         *                 allowing the remainder of the MP positions to be relative to
1005         *                 zero.
1006         *              timeDur Duration to apply this trajectory pt.
1007         *                              This time unit is ADDED to the exising base time set by
1008         *                              configMotionProfileTrajectoryPeriod().
1009         * @return CTR_OKAY if trajectory point push ok. ErrorCode if buffer is
1010         *         full due to kMotionProfileTopBufferCapacity.
1011         */
1012        public ErrorCode pushMotionProfileTrajectory(TrajectoryPoint trajPt);
1013        /**
1014         * Retrieve just the buffer full for the api-level (top) buffer. This
1015         * routine performs no CAN or data structure lookups, so its fast and ideal
1016         * if caller needs to quickly poll. Otherwise just use
1017         * GetMotionProfileStatus.
1018         *
1019         * @return number of trajectory points in the top buffer.
1020         */
1021        public boolean isMotionProfileTopLevelBufferFull();
1022        /**
1023         * This must be called periodically to funnel the trajectory points from the
1024         * API's top level buffer to the controller's bottom level buffer. Recommendation
1025         * is to call this twice as fast as the execution rate of the motion
1026         * profile. So if MP is running with 20ms trajectory points, try calling
1027         * this routine every 10ms. All motion profile functions are thread-safe
1028         * through the use of a mutex, so there is no harm in having the caller
1029         * utilize threading.
1030         */
1031        public void processMotionProfileBuffer();
1032        /**
1033         * Retrieve all status information.
1034         * For best performance, Caller can snapshot all status information regarding the
1035         * motion profile executer.
1036         *
1037         * @param statusToFill  Caller supplied object to fill.
1038         *
1039         * The members are filled, as follows...
1040         *
1041         *      topBufferRem:   The available empty slots in the trajectory buffer.
1042         *                                      The robot API holds a "top buffer" of trajectory points, so your applicaion
1043         *                                      can dump several points at once.  The API will then stream them into the
1044         *                                      low-level buffer, allowing the motor controller to act on them.
1045         *
1046         *      topBufferRem: The number of points in the top trajectory buffer.
1047         *
1048         *      btmBufferCnt: The number of points in the low level controller buffer.
1049         *
1050         *      hasUnderrun:    Set if isUnderrun ever gets set.
1051         *                                      Can be manually cleared by clearMotionProfileHasUnderrun() or automatically cleared by startMotionProfile().
1052         *
1053         *      isUnderrun:             This is set if controller needs to shift a point from its buffer into
1054         *                                      the active trajectory point however
1055         *                                      the buffer is empty.
1056         *                                      This gets cleared automatically when is resolved.
1057         *
1058         *      activePointValid:       True if the active trajectory point is not empty, false otherwise. The members in activePoint are only valid if this signal is set.
1059         *
1060         *      isLast: is set/cleared based on the MP executer's current
1061         *                trajectory point's IsLast value.  This assumes
1062         *                IsLast was set when PushMotionProfileTrajectory
1063         *                was used to insert the currently processed trajectory
1064         *                point.
1065         *
1066         *      profileSlotSelect: The currently processed trajectory point's
1067         *                                selected slot.  This can differ in the currently selected slot used
1068         *                                       for Position and Velocity servo modes
1069         *
1070         *      outputEnable:           The current output mode of the motion profile
1071         *                                              executer (disabled, enabled, or hold).  When changing the set()
1072         *                                              value in MP mode, it's important to check this signal to
1073         *                                              confirm the change takes effect before interacting with the top buffer.
1074         * @return Error Code generated by function. 0 indicates no error.
1075         */
1076        public ErrorCode getMotionProfileStatus(MotionProfileStatus statusToFill);
1077        /**
1078         * Clear the "Has Underrun" flag. Typically this is called after application
1079         * has confirmed an underrun had occured.
1080         *
1081         * @param timeoutMs
1082         *            Timeout value in ms. If nonzero, function will wait for config
1083         *            success and report an error if it times out. If zero, no
1084         *            blocking or checking is performed.
1085         * @return Error Code generated by function. 0 indicates no error.
1086         */
1087        public ErrorCode clearMotionProfileHasUnderrun(int timeoutMs);
1088        /**
1089         * Calling application can opt to speed up the handshaking between the robot
1090         * API and the controller to increase the download rate of the controller's Motion
1091         * Profile. Ideally the period should be no more than half the period of a
1092         * trajectory point.
1093         *
1094         * @param periodMs
1095         *            The transmit period in ms.
1096         * @return Error Code generated by function. 0 indicates no error.
1097         */
1098        public ErrorCode changeMotionControlFramePeriod(int periodMs);
1099
1100        // ------ error ----------//
1101        /**
1102         * Gets the last error generated by this object. Not all functions return an
1103         * error code but can potentially report errors. This function can be used
1104         * to retrieve those error codes.
1105         *
1106         * @return Last Error Code generated by a function.
1107         */
1108        public ErrorCode getLastError();
1109
1110        // ------ Faults ----------//
1111        /**
1112         * Polls the various fault flags.
1113         *
1114         * @param toFill
1115         *            Caller's object to fill with latest fault flags.
1116         * @return Last Error Code generated by a function.
1117         */
1118        public ErrorCode getFaults(Faults toFill) ;
1119
1120        /**
1121         * Polls the various sticky fault flags.
1122         *
1123         * @param toFill
1124         *            Caller's object to fill with latest sticky fault flags.
1125         * @return Last Error Code generated by a function.
1126         */
1127        public ErrorCode getStickyFaults(StickyFaults toFill) ;
1128
1129        /**
1130         * Clears all sticky faults.
1131         *
1132         * @param timeoutMs
1133         *            Timeout value in ms. If nonzero, function will wait for config
1134         *            success and report an error if it times out. If zero, no
1135         *            blocking or checking is performed.
1136         * @return Last Error Code generated by a function.
1137         */
1138        public ErrorCode clearStickyFaults(int timeoutMs);
1139
1140        // ------ Firmware ----------//
1141        /**
1142         * Gets the firmware version of the device.
1143         *
1144         * @return Firmware version of device. For example: version 1-dot-2 is
1145         *         0x0102.
1146         */
1147        public int getFirmwareVersion();
1148
1149        /**
1150         * Returns true if the device has reset since last call.
1151         *
1152         * @return Has a Device Reset Occurred?
1153         */
1154        public boolean hasResetOccurred();
1155
1156        // ------ Custom Persistent Params ----------//
1157        /**
1158         * Sets the value of a custom parameter. This is for arbitrary use.
1159         *
1160         * Sometimes it is necessary to save calibration/limit/target information in
1161         * the device. Particularly if the device is part of a subsystem that can be
1162         * replaced.
1163         *
1164         * @param newValue
1165         *            Value for custom parameter.
1166         * @param paramIndex
1167         *            Index of custom parameter [0,1]
1168         * @param timeoutMs
1169         *            Timeout value in ms. If nonzero, function will wait for config
1170         *            success and report an error if it times out. If zero, no
1171         *            blocking or checking is performed.
1172         * @return Error Code generated by function. 0 indicates no error.
1173         */
1174        public ErrorCode configSetCustomParam(int newValue, int paramIndex, int timeoutMs);
1175
1176        /**
1177         * Gets the value of a custom parameter.
1178         *
1179         * @param paramIndex
1180         *            Index of custom parameter [0,1].
1181         * @param timeoutMs
1182         *            Timeout value in ms. If nonzero, function will wait for config
1183         *            success and report an error if it times out. If zero, no
1184         *            blocking or checking is performed.
1185         * @return Value of the custom param.
1186         */
1187        public int configGetCustomParam(int paramIndex, int timeoutMs);
1188
1189        //------ Generic Param API, typically not used ----------//
1190        /**
1191         * Sets a parameter. Generally this is not used. This can be utilized in -
1192         * Using new features without updating API installation. - Errata
1193         * workarounds to circumvent API implementation. - Allows for rapid testing
1194         * / unit testing of firmware.
1195         *
1196         * @param param
1197         *            Parameter enumeration.
1198         * @param value
1199         *            Value of parameter.
1200         * @param subValue
1201         *            Subvalue for parameter. Maximum value of 255.
1202         * @param ordinal
1203         *            Ordinal of parameter.
1204         * @param timeoutMs
1205         *            Timeout value in ms. If nonzero, function will wait for config
1206         *            success and report an error if it times out. If zero, no
1207         *            blocking or checking is performed.
1208         * @return Error Code generated by function. 0 indicates no error.
1209         */
1210        public ErrorCode configSetParameter(ParamEnum param, double value, int subValue, int ordinal, int timeoutMs);
1211        /**
1212         * Sets a parameter.
1213         *
1214         * @param param
1215         *            Parameter enumeration.
1216         * @param value
1217         *            Value of parameter.
1218         * @param subValue
1219         *            Subvalue for parameter. Maximum value of 255.
1220         * @param ordinal
1221         *            Ordinal of parameter.
1222         * @param timeoutMs
1223         *            Timeout value in ms. If nonzero, function will wait for
1224         *            config success and report an error if it times out.
1225         *            If zero, no blocking or checking is performed.
1226         * @return Error Code generated by function. 0 indicates no error.
1227         */
1228        public ErrorCode configSetParameter(int param, double value, int subValue, int ordinal, int timeoutMs);
1229
1230        /**
1231         * Gets a parameter.
1232         *
1233         * @param paramEnum
1234         *            Parameter enumeration.
1235         * @param ordinal
1236         *            Ordinal of parameter.
1237         * @param timeoutMs
1238         *            Timeout value in ms. If nonzero, function will wait for
1239         *            config success and report an error if it times out.
1240         *            If zero, no blocking or checking is performed.
1241         * @return Value of parameter.
1242         */
1243        public double configGetParameter(ParamEnum paramEnum, int ordinal, int timeoutMs) ;
1244        /**
1245         * Gets a parameter.
1246         *
1247         * @param paramEnum
1248         *            Parameter enumeration.
1249         * @param ordinal
1250         *            Ordinal of parameter.
1251         * @param timeoutMs
1252         *            Timeout value in ms. If nonzero, function will wait for
1253         *            config success and report an error if it times out.
1254         *            If zero, no blocking or checking is performed.
1255         * @return Value of parameter.
1256         */
1257        public double configGetParameter(int paramEnum, int ordinal, int timeoutMs) ;
1258
1259        //------ Misc. ----------//
1260        /**
1261         * @return BaseID of device
1262         */
1263        public int getBaseID();
1264        /**
1265         * Returns the Device ID
1266         *
1267         * @return Device number.
1268         */
1269        public int getDeviceID();
1270        /**
1271         * @return control mode motor controller is in
1272         */
1273        public ControlMode getControlMode();
1274        // ----- Follower ------//
1275        /* in parent interface */
1276}