001/*
002 *  Software License Agreement
003 *
004 * Copyright (C) Cross The Road Electronics.  All rights
005 * reserved.
006 *
007 * Cross The Road Electronics (CTRE) licenses to you the right to
008 * use, publish, and distribute copies of CRF (Cross The Road) firmware files (*.crf) and Software
009 * API Libraries ONLY when in use with Cross The Road Electronics hardware products.
010 *
011 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
012 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
013 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
014 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
015 * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
016 * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
017 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
018 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
019 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
020 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
021 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE
022 */
023package com.ctre.phoenix.sensors;
024import com.ctre.phoenix.ErrorCode;
025import com.ctre.phoenix.ParamEnum;
026import com.ctre.phoenix.motorcontrol.can.TalonSRX;
027import com.ctre.phoenix.ErrorCollection;
028import com.ctre.phoenix.CustomParamConfigUtil;
029
030//import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType;
031//import edu.wpi.first.wpilibj.hal.HAL;
032
033/**
034 * Pigeon IMU Class. Class supports communicating over CANbus and over
035 * ribbon-cable (CAN Talon SRX).
036 */
037public class PigeonIMU extends BasePigeon {
038
039        /** Data object for holding fusion information. */
040        public static class FusionStatus {
041                /**
042                 * Fused Heading
043                 */
044                public double heading;
045                /**
046                 * Whether the fusion is valid
047                 */
048                public boolean bIsValid;
049                /**
050                 * Whether the pigeon is fusing
051                 */
052                public boolean bIsFusing;
053
054                /**
055                 * Same as getLastError()
056                 */
057                public ErrorCode lastError;
058
059                /**
060                 * @return status of fusion as a string 
061                 */
062                public String toString() {
063                        String description;
064                        if (lastError != ErrorCode.OK) {
065                                description = "Could not receive status frame.  Check wiring and Phoenix Tuner.";
066                        } else if (bIsValid == false) {
067                                description = "Fused Heading is not valid.";
068                        } else if (bIsFusing == false) {
069                                description = "Fused Heading is valid.";
070                        } else {
071                                description = "Fused Heading is valid and is fusing compass.";
072                        }
073                        return description;
074                }
075        }
076
077        /** 
078         * Various calibration modes supported by Pigeon. 
079         *
080         * Note that you can instead use Phoenix Tuner to accomplish certain calibrations.
081         *
082         */
083        public enum CalibrationMode {
084                /**
085                 * Boot-Calibrate the pigeon
086                 */
087                BootTareGyroAccel(0), 
088                /**
089                 * Temperature-Calibrate the pigeon
090                 */
091                Temperature(1), 
092                /**
093                 * Magnetometer-Calibrate the pigeon using the 12pt process
094                 */
095                Magnetometer12Pt(2), 
096                /**
097                 * Magnetometer-Calibrate the pigeon using 360 turns
098                 */
099                Magnetometer360(3), 
100                /**
101                 * Calibrate the pigeon accelerometer
102                 */
103                Accelerometer(5), 
104                /**
105                 * Unknown calibration
106                 */
107                Unknown(-1);
108
109                /**
110                 * Value of CalibrationMode
111                 */
112                public final int value;
113
114                private CalibrationMode(int initValue) {
115                        this.value = initValue;
116                }
117
118                /**
119                 * Get a CalibrationMode of specified value
120                 * @param value Value of CalibrationMode
121                 * @return CalibrationMode of specified value
122                 */
123                public static CalibrationMode valueOf(int value) {
124                        for (CalibrationMode e : CalibrationMode.values()) {
125                                if (e.value == value) {
126                                        return e;
127                                }
128                        }
129                        return Unknown;
130                }
131        };
132
133        /** Overall state of the Pigeon. */
134        public enum PigeonState {
135                /**
136                 * No communications with Pigeon
137                 */
138                NoComm(0), 
139                /**
140                 * Pigeon is initializing
141                 */
142                Initializing(1), 
143                /**
144                 * Pigeon is ready
145                 */
146                Ready(2), 
147                /**
148                 * Pigeon is calibrating due to user
149                 */
150                UserCalibration(3), 
151                /**
152                 * Unknown state
153                 */
154                Unknown(-1);
155
156                /**
157                 * Value of PigeonState
158                 */
159                public final int value;
160
161                private PigeonState(int initValue) {
162                        this.value = initValue;
163                }
164
165                /**
166                 * Get a PigeonState of specified value
167                 * @param value Value of PigeonState
168                 * @return PigeonState of specified value
169                 */
170                public static PigeonState valueOf(int value) {
171                        for (PigeonState e : PigeonState.values()) {
172                                if (e.value == value) {
173                                        return e;
174                                }
175                        }
176                        return Unknown;
177                }
178        };
179
180        /**
181         * Data object for status on current calibration and general status.
182         *
183         * Pigeon has many calibration modes supported for a variety of uses. The
184         * modes generally collects and saves persistently information that makes
185         * the Pigeon signals more accurate. This includes collecting temperature,
186         * gyro, accelerometer, and compass information.
187         *
188         * For FRC use-cases, typically compass and temperature calibration is not
189         * required.
190         *
191         * Additionally when motion driver software in the Pigeon boots, it will
192         * perform a fast boot calibration to initially bias gyro and setup
193         * accelerometer.
194         *
195         * These modes can be enabled with the EnterCalibration mode.
196         *
197         * When a calibration mode is entered, caller can expect...
198         *
199         * - PigeonState to reset to Initializing and bCalIsBooting is set to true.
200         * Pigeon LEDs will blink the boot pattern. This is similar to the normal
201         * boot cal, however it can an additional ~30 seconds since calibration
202         * generally requires more information. currentMode will reflect the user's
203         * selected calibration mode.
204         *
205         * - PigeonState will eventually settle to UserCalibration and Pigeon LEDs
206         * will show cal specific blink patterns. bCalIsBooting is now false.
207         *
208         * - Follow the instructions in the Pigeon User Manual to meet the
209         * calibration specific requirements. When finished calibrationError will
210         * update with the result. Pigeon will solid-fill LEDs with red (for
211         * failure) or green (for success) for ~5 seconds. Pigeon then perform
212         * boot-cal to cleanly apply the newly saved calibration data.
213         */
214        public static class GeneralStatus {
215                /**
216                 * The current state of the motion driver. This reflects if the sensor
217                 * signals are accurate. Most calibration modes will force Pigeon to
218                 * reinit the motion driver.
219                 */
220                public PigeonState state;
221                /**
222                 * The currently applied calibration mode if state is in UserCalibration
223                 * or if bCalIsBooting is true. Otherwise it holds the last selected
224                 * calibration mode (when calibrationError was updated).
225                 */
226                public CalibrationMode currentMode;
227                /**
228                 * The error code for the last calibration mode. Zero represents a
229                 * successful cal (with solid green LEDs at end of cal) and nonzero is a
230                 * failed calibration (with solid red LEDs at end of cal). Different
231                 * calibration
232                 */
233                public int calibrationError;
234                /**
235                 * After caller requests a calibration mode, pigeon will perform a
236                 * boot-cal before entering the requested mode. During this period, this
237                 * flag is set to true.
238                 */
239                public boolean bCalIsBooting;
240                /**
241                 * Temperature in Celsius
242                 */
243                public double tempC;
244                /**
245                 * Number of seconds Pigeon has been up (since boot). This register is
246                 * reset on power boot or processor reset. Register is capped at 255
247                 * seconds with no wrap around.
248                 */
249                public int upTimeSec;
250                /**
251                 * Number of times the Pigeon has automatically rebiased the gyro. This
252                 * counter overflows from 15 -> 0 with no cap.
253                 */
254                public int noMotionBiasCount;
255                /**
256                 * Number of times the Pigeon has temperature compensated the various
257                 * signals. This counter overflows from 15 -> 0 with no cap.
258                 */
259                public int tempCompensationCount;
260                /**
261                 * Same as getLastError()
262                 */
263                public ErrorCode lastError;
264
265                /**
266                 * general string description of current status
267                 */
268                public String toString() {
269                        String description;
270                        /* build description string */
271                        if (lastError != ErrorCode.OK) { // same as NoComm
272                                description = "Status frame was not received, check wired connections and Phoenix Tuner.";
273                        } else if (bCalIsBooting) {
274                                description = "Pigeon is boot-caling to properly bias accel and gyro.  Do not move Pigeon.  When finished biasing, calibration mode will start.";
275                        } else if (state == PigeonState.UserCalibration) {
276                                /* mode specific descriptions */
277                                switch (currentMode) {
278                                case BootTareGyroAccel:
279                                        description = "Boot-Calibration: Gyro and Accelerometer are being biased.";
280                                        break;
281                                case Temperature:
282                                        description = "Temperature-Calibration: Pigeon is collecting temp data and will finish when temp range is reached. \n";
283                                        description += "Do not move Pigeon.";
284                                        break;
285                                case Magnetometer12Pt:
286                                        description = "Magnetometer Level 1 calibration: Orient the Pigeon PCB in the 12 positions documented in the User's Manual.";
287                                        break;
288                                case Magnetometer360:
289                                        description = "Magnetometer Level 2 calibration: Spin robot slowly in 360' fashion.  ";
290                                        break;
291                                case Accelerometer:
292                                        description = "Accelerometer Calibration: Pigeon PCB must be placed on a level source.  Follow User's Guide for how to level surfacee.  ";
293                                        break;
294                                default:
295                                case Unknown:
296                                        description = "Unknown status";
297                                        break;
298                                }
299                        } else if (state == PigeonState.Ready) {
300                                /*
301                                 * definitely not doing anything cal-related. So just instrument
302                                 * the motion driver state
303                                 */
304                                description = "Pigeon is running normally.  Last CAL error code was ";
305                                description += Integer.toString(calibrationError);
306                                description += ".";
307                        } else if (state == PigeonState.Initializing) {
308                                /*
309                                 * definitely not doing anything cal-related. So just instrument
310                                 * the motion driver state
311                                 */
312                                description = "Pigeon is boot-caling to properly bias accel and gyro.  Do not move Pigeon.";
313                        } else {
314                                description = "Not enough data to determine status.";
315                        }
316                        return description;
317                }
318        };
319
320        private double[] _generalStatus = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
321        private double[] _fusionStatus = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
322
323        /**
324         * Create a Pigeon object that communicates with Pigeon on CAN Bus.
325         *
326         * @param deviceNumber
327         *            CAN Device Id of Pigeon [0,62]
328         */
329        public PigeonIMU(int deviceNumber) {
330                super(deviceNumber, "v1");
331        }
332
333    //public static void DestroyAllPigeonIMUs() {
334    //    PigeonImuJNI.JNI_destroy_AllPigeonImus();
335    //}
336
337        /**
338         * Create a Pigeon object that communciates with Pigeon through the
339         * Gadgeteer ribbon cable connected to a Talon on CAN Bus.
340         *
341         * @param talonSrx
342         *            Object for the TalonSRX connected via ribbon cable.
343         */
344        public PigeonIMU(TalonSRX talonSrx) {
345                super(PigeonImuJNI.JNI_new_PigeonImu_Talon(talonSrx.getDeviceID(), "v1"));
346        }
347
348        /**
349         * Sets the Fused Heading to the specified value.
350         *
351         * @param angleDeg  New fused-heading in degrees [+/- 23,040 degrees]
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 setFusedHeading(double angleDeg, int timeoutMs) {
359                int retval = PigeonImuJNI.JNI_SetFusedHeading(getHandle(), angleDeg, timeoutMs);
360                return ErrorCode.valueOf(retval);
361        }
362        /**
363         * Sets the Fused Heading to the specified value.
364         *
365         * @param angleDeg  New fused-heading in degrees [+/- 23,040 degrees]
366         * @return Error Code generated by function. 0 indicates no error.
367         */
368        public ErrorCode setFusedHeading(double angleDeg) {
369                int timeoutMs = 0;
370                return setFusedHeading( angleDeg,  timeoutMs);
371        }
372        /**
373         * Atomically add to the Fused Heading register.
374         *
375         * @param angleDeg  Degrees to add to the Fused Heading register.
376         * @param timeoutMs
377     *            Timeout value in ms. If nonzero, function will wait for
378     *            config success and report an error if it times out.
379     *            If zero, no blocking or checking is performed.
380         * @return Error Code generated by function. 0 indicates no error.
381         */
382        public ErrorCode addFusedHeading(double angleDeg, int timeoutMs) {
383                int retval = PigeonImuJNI.JNI_AddFusedHeading(getHandle(), angleDeg, timeoutMs);
384                return ErrorCode.valueOf(retval);
385        }
386        /**
387         * Atomically add to the Fused Heading register.
388         *
389         * @param angleDeg  Degrees to add to the Fused Heading register
390         * @return Error Code generated by function. 0 indicates no error.
391         */
392        public ErrorCode addFusedHeading(double angleDeg) {
393                int timeoutMs = 0;
394                return addFusedHeading(angleDeg, timeoutMs);
395        }
396        /**
397         * Sets the Fused Heading register to match the current compass value.
398         *
399         * @param timeoutMs
400     *            Timeout value in ms. If nonzero, function will wait for
401     *            config success and report an error if it times out.
402     *            If zero, no blocking or checking is performed.
403         * @return Error Code generated by function. 0 indicates no error.
404         */
405        public ErrorCode setFusedHeadingToCompass(int timeoutMs) {
406                int retval = PigeonImuJNI.JNI_SetFusedHeadingToCompass(getHandle(), timeoutMs);
407                return ErrorCode.valueOf(retval);
408        }
409        /**
410         * Sets the Fused Heading register to match the current compass value.
411         *
412         * @return Error Code generated by function. 0 indicates no error.
413         */
414        public ErrorCode setFusedHeadingToCompass() {
415                int timeoutMs = 0;
416                return setFusedHeadingToCompass(timeoutMs);
417        }
418
419    /**
420     * Disable/Enable Temp compensation. Pigeon has this on/False at boot.
421     *
422     * @param bTempCompDisable Set to "False" to enable temperature compensation.
423     * @param timeoutMs
424     *            Timeout value in ms. If nonzero, function will wait for
425     *            config success and report an error if it times out.
426     *            If zero, no blocking or checking is performed.
427     * @return Error Code generated by function. 0 indicates no error.
428     */
429        public ErrorCode setTemperatureCompensationDisable(boolean bTempCompDisable, int timeoutMs) {
430                int retval = PigeonImuJNI.JNI_SetTemperatureCompensationDisable(getHandle(), bTempCompDisable ? 1 : 0, timeoutMs);
431                return ErrorCode.valueOf(retval);
432        }
433    /**
434     * Disable/Enable Temp compensation. Pigeon has this on/False at boot.
435     *
436     * @param bTempCompDisable Set to "False" to enable temperature compensation.
437     * @return Error Code generated by function. 0 indicates no error.
438     */
439        public ErrorCode setTemperatureCompensationDisable(boolean bTempCompDisable) {
440                int timeoutMs = 0;
441                return setTemperatureCompensationDisable(bTempCompDisable, timeoutMs);
442        }
443
444        /**
445         * Set the declination for compass. Declination is the difference between
446         * Earth Magnetic north, and the geographic "True North".
447         *
448         * @param angleDegOffset  Degrees to set Compass Declination to.
449         * @param timeoutMs
450     *            Timeout value in ms. If nonzero, function will wait for
451     *            config success and report an error if it times out.
452     *            If zero, no blocking or checking is performed.
453         * @return Error Code generated by function. 0 indicates no error.
454         */
455        public ErrorCode setCompassDeclination(double angleDegOffset, int timeoutMs) {
456                int retval = PigeonImuJNI.JNI_SetCompassDeclination(getHandle(), angleDegOffset, timeoutMs);
457                return ErrorCode.valueOf(retval);
458        }
459        /**
460         * Set the declination for compass. Declination is the difference between
461         * Earth Magnetic north, and the geographic "True North".
462         *
463         * @param angleDegOffset  Degrees to set Compass Declination to.
464         * @return Error Code generated by function. 0 indicates no error.
465         */
466        public ErrorCode setCompassDeclination(double angleDegOffset) {
467                int timeoutMs = 0;
468                return setCompassDeclination( angleDegOffset, timeoutMs);
469        }
470
471        /**
472         * Sets the compass angle. Although compass is absolute [0,360) degrees, the
473         * continuous compass register holds the wrap-arounds.
474         *
475         * @param angleDeg  Degrees to set continuous compass angle to.
476         * @param timeoutMs
477     *            Timeout value in ms. If nonzero, function will wait for
478     *            config success and report an error if it times out.
479     *            If zero, no blocking or checking is performed.
480         * @return Error Code generated by function. 0 indicates no error.
481         */
482        public ErrorCode setCompassAngle(double angleDeg, int timeoutMs) {
483                int retval = PigeonImuJNI.JNI_SetCompassAngle(getHandle(), angleDeg, timeoutMs);
484                return ErrorCode.valueOf(retval);
485        }
486        /**
487         * Sets the compass angle. Although compass is absolute [0,360) degrees, the
488         * continuous compass register holds the wrap-arounds.
489         *
490         * @param angleDeg  Degrees to set continuous compass angle to.
491         * @return Error Code generated by function. 0 indicates no error.
492         */
493        public ErrorCode setCompassAngle(double angleDeg) {
494                int timeoutMs = 0;
495                return setCompassAngle(angleDeg, timeoutMs);
496        }
497
498        // ----------------------- Calibration routines -----------------------//
499        /**
500         * Enters the Calbration mode.  See the Pigeon IMU documentation for More
501         * information on Calibration.
502         *
503         * Note that you can instead use Phoenix Tuner to accomplish this.
504         * Note you should NOT be calling this during normal robot operation.
505         *
506         * @param calMode  Calibration to execute
507         * @param timeoutMs
508     *            Timeout value in ms. If nonzero, function will wait for
509     *            config success and report an error if it times out.
510     *            If zero, no blocking or checking is performed.
511         * @return Error Code generated by function. 0 indicates no error.
512         */
513        public ErrorCode enterCalibrationMode(CalibrationMode calMode, int timeoutMs) {
514                int retval = PigeonImuJNI.JNI_EnterCalibrationMode(getHandle(), calMode.value, timeoutMs);
515                return ErrorCode.valueOf(retval);
516        }
517        /**
518         * Enters the Calbration mode.  See the Pigeon IMU documentation for More
519         * information on Calibration.
520         *
521         * Note that you can instead use Phoenix Tuner to accomplish this.
522         * Note you should not be using this in your normal robot application.
523         *
524         * @param calMode  Calibration to execute
525         * @return Error Code generated by function. 0 indicates no error.
526         */
527        public ErrorCode enterCalibrationMode(CalibrationMode calMode) {
528                int timeoutMs = 0;
529                return enterCalibrationMode(calMode, timeoutMs);
530        }
531
532        /**
533         * Get the status of the current (or previousley complete) calibration.
534         *
535         * @param toFill Container for the status information.
536         * @return Error Code generated by function. 0 indicates no error.
537         */
538        public ErrorCode getGeneralStatus(GeneralStatus toFill) {
539                int retval = PigeonImuJNI.JNI_GetGeneralStatus(getHandle(), _generalStatus);
540                toFill.state = PigeonState.valueOf((int) _generalStatus[0]);
541                toFill.currentMode = CalibrationMode.valueOf((int) _generalStatus[1]);
542                toFill.calibrationError = (int) _generalStatus[2];
543                toFill.bCalIsBooting = _generalStatus[3] != 0;
544                toFill.tempC = _generalStatus[4];
545                toFill.upTimeSec = (int) _generalStatus[5];
546                toFill.noMotionBiasCount = (int) _generalStatus[6];
547                toFill.tempCompensationCount = (int) _generalStatus[7];
548                toFill.lastError = ErrorCode.valueOf(retval);
549                return toFill.lastError;
550        }
551
552        /**
553         * Gets the current Pigeon state
554         *
555         * @return PigeonState enum
556         */
557        public PigeonState getState() {
558                int retval = PigeonImuJNI.JNI_GetState(getHandle());
559                return PigeonState.valueOf(retval);
560        }
561
562        /**
563         * Get the current Fusion Status (including fused heading)
564         *
565         * @param toFill        object reference to fill with fusion status flags.
566         *                                      Caller may pass null if flags are not needed.
567         * @return The fused heading in degrees.
568         */
569        public double getFusedHeading(FusionStatus toFill) {
570                int errorCode = PigeonImuJNI.JNI_GetFusedHeading(getHandle(), _fusionStatus);
571
572                if (toFill != null) {
573                        toFill.heading = _fusionStatus[0];
574                        toFill.bIsFusing = (_fusionStatus[1] != 0);
575                        toFill.bIsValid = (_fusionStatus[2] != 0);
576                        toFill.lastError = ErrorCode.valueOf(errorCode);
577                }
578
579                return _fusionStatus[0];
580        }
581        /**
582         * Gets the Fused Heading
583         *
584         * @return The fused heading in degrees.
585         */
586        public double getFusedHeading() {
587                PigeonImuJNI.JNI_GetFusedHeading(getHandle(), _fusionStatus);
588
589                return _fusionStatus[0];
590        }
591        
592        /**
593         * Get Accelerometer tilt angles.
594         *
595         * @param tiltAngles Array to fill with x[0], y[1], and z[2] angles in degrees.
596         * @return The last ErrorCode generated.
597         */
598        public ErrorCode getAccelerometerAngles(double[] tiltAngles) {
599                int retval = PigeonImuJNI.JNI_GetAccelerometerAngles(getHandle(), tiltAngles);
600                return ErrorCode.valueOf(retval);
601        }
602
603    /**
604     * Configures all persistent settings.
605     *
606         * @param allConfigs        Object with all of the persistant settings
607     * @param timeoutMs
608     *              Timeout value in ms. If nonzero, function will wait for
609     *              config success and report an error if it times out.
610     *              If zero, no blocking or checking is performed.
611     *
612     * @return Error Code generated by function. 0 indicates no error. 
613     */
614        public ErrorCode configAllSettings(PigeonIMUConfiguration allConfigs, int timeoutMs) {
615        ErrorCollection errorCollection = new ErrorCollection();
616                
617                errorCollection.NewError(configFactoryDefault(timeoutMs));
618                
619                if(CustomParamConfigUtil.customParam0Different(allConfigs))
620                        errorCollection.NewError(configSetCustomParam(allConfigs.customParam0, 0, timeoutMs));
621                if(CustomParamConfigUtil.customParam1Different(allConfigs))
622                        errorCollection.NewError(configSetCustomParam(allConfigs.customParam1, 1, timeoutMs));
623        
624
625        return errorCollection._worstError;
626
627        }
628    /**
629     * Configures all persistent settings (overloaded so timeoutMs is 50 ms).
630     *
631         * @param allConfigs        Object with all of the persistant settings
632     *
633     * @return Error Code generated by function. 0 indicates no error. 
634     */
635        public ErrorCode configAllSettings(PigeonIMUConfiguration allConfigs) {
636                int timeoutMs = 0;
637                return  configAllSettings(allConfigs, timeoutMs);
638        }
639    /**
640     * Gets all persistant settings.
641     *
642         * @param allConfigs        Object with all of the persistant settings
643     * @param timeoutMs
644     *              Timeout value in ms. If nonzero, function will wait for
645     *              config success and report an error if it times out.
646     *              If zero, no blocking or checking is performed.
647     */
648    public void getAllConfigs(PigeonIMUConfiguration allConfigs, int timeoutMs) {
649
650        allConfigs.customParam0 = (int) configGetParameter(ParamEnum.eCustomParam, 0,  timeoutMs);
651        allConfigs.customParam1 = (int) configGetParameter(ParamEnum.eCustomParam, 1,  timeoutMs);
652    }
653    /**
654     * Gets all persistant settings (overloaded so timeoutMs is 50 ms).
655     *
656         * @param allConfigs        Object with all of the persistant settings
657     */
658    public void getAllConfigs(PigeonIMUConfiguration allConfigs) {
659        int timeoutMs = 50;
660        getAllConfigs(allConfigs, timeoutMs);
661    }   
662    /**
663     * Configures all persistent settings to defaults.
664     *
665     * @param timeoutMs
666     *              Timeout value in ms. If nonzero, function will wait for
667     *              config success and report an error if it times out.
668     *              If zero, no blocking or checking is performed.
669     *
670     * @return Error Code generated by function. 0 indicates no error. 
671     */
672        public ErrorCode configFactoryDefault(int timeoutMs) {
673                return ErrorCode.valueOf(PigeonImuJNI.JNI_ConfigFactoryDefault(getHandle(), timeoutMs));
674        }
675    /**
676     * Configures all persistent settings to defaults (overloaded so timeoutMs is 50 ms).
677     *
678     * @return Error Code generated by function. 0 indicates no error. 
679     */
680        public ErrorCode configFactoryDefault() {
681                int timeoutMs = 50;
682                return configFactoryDefault(timeoutMs);
683                
684        }
685        /**
686         * Gets the fault status
687         *
688         * @param toFill
689         *            Container for fault statuses.
690         * @return Error Code generated by function. 0 indicates no error.
691         */
692        public ErrorCode getFaults(PigeonIMU_Faults toFill) {
693                int bits = PigeonImuJNI.JNI_GetFaults(getHandle());
694                toFill.update(bits);
695                return getLastError();
696        }
697        /**
698         * Gets the sticky fault status
699         *
700         * @param toFill
701         *            Container for sticky fault statuses.
702         * @return Error Code generated by function. 0 indicates no error.
703         */
704        public ErrorCode getStickyFaults(PigeonIMU_Faults toFill) {
705                int bits = PigeonImuJNI.JNI_GetStickyFaults(getHandle());
706                toFill.update(bits);
707                return getLastError();
708        }
709
710}