frclib/CanJag.h
author Trc492/3543
Sun Aug 12 10:02:33 2012 -0700 (2012-08-12)
changeset 292 34b81ee90375
parent 227 1edefc0b7437
permissions -rw-r--r--
Up drive power to 50%
     1 #if 0
     2 /// Copyright (c) Titan Robotics Club. All rights reserved.
     3 ///
     4 /// <module name="CanJag.h" />
     5 ///
     6 /// <summary>
     7 ///     This module contains the definition and implementation of the
     8 ///     CanJag class.
     9 /// </summary>
    10 ///
    11 /// <remarks>
    12 ///     Environment: Wind River C++ for National Instrument cRIO based Robot.
    13 /// </remarks>
    14 #endif
    15 
    16 #ifndef _CANJAG_H
    17 #define _CANJAG_H
    18 
    19 #ifdef MOD_ID
    20     #undef MOD_ID
    21 #endif
    22 #define MOD_ID                  MOD_CANJAG
    23 #ifdef MOD_NAME
    24     #undef MOD_NAME
    25 #endif
    26 #define MOD_NAME                "CanJag"
    27 
    28 /**
    29  * This class defines and implements the CanJag object. The CanJag object
    30  * inherits from the CANJaguar object in the WPI library. It basically wraps
    31  * the CANJaguar class so it can shadow all the volatile Jaguar configuration
    32  * parameters. If the Jaguar ever browns out, we will be able to restore the
    33  * Jaguar configurations.
    34  */
    35 class CanJag: public CANJaguar
    36 {
    37 private:
    38     UINT16              m_encoderLines;
    39     UINT16              m_potTurns;
    40     float               m_faultTime;
    41     NeutralMode         m_neutralMode;
    42     double              m_fwdLimitPos;
    43     double              m_revLimitPos;
    44     double              m_voltRampRate;
    45 
    46     SpeedReference      m_speedRef;
    47     PositionReference   m_posRef;
    48     double              m_Kp;
    49     double              m_Ki;
    50     double              m_Kd;
    51 
    52     bool                m_fPowerCycled;
    53     float               m_motorValue;
    54     double              m_position;
    55     double              m_speed;
    56 
    57 #ifdef _CANJAG_PERF
    58     PerfData           *m_setMotorPerfData;
    59     PerfData           *m_getPosPerfData;
    60     PerfData           *m_getSpeedPerfData;
    61 #endif
    62 
    63     /**
    64      * This funcion checks if a power cycle has occurred. If so, it will
    65      * reconfigure the Jaguar with the shadowed information.
    66      *
    67      * @return Returns true if the Jaguar has been power cycled since we
    68      *         check last.
    69      */
    70     bool
    71     CheckPowerCycled(
    72         void
    73         )
    74     {
    75         TLevel(FUNC);
    76         TEnter();
    77 
    78         m_fPowerCycled = GetPowerCycled();
    79         if (m_fPowerCycled)
    80         {
    81             //
    82             // Jaguar has lost power, restore configuration appropriately.
    83             //
    84             TWarn(("Detected brownout on Jag %d.", m_deviceNumber));
    85             CANJaguar::ChangeControlMode(m_controlMode);
    86             if (m_controlMode == kPosition)
    87             {
    88                 CANJaguar::SetPID(m_Kp, m_Ki, m_Kd);
    89                 CANJaguar::SetPositionReference(m_posRef);
    90                 if (m_posRef == kPosRef_QuadEncoder)
    91                 {
    92                     CANJaguar::ConfigEncoderCodesPerRev(m_encoderLines);
    93                 }
    94                 else if (m_posRef == kPosRef_Potentiometer)
    95                 {
    96                     CANJaguar::ConfigPotentiometerTurns(m_potTurns);
    97                 }
    98             }
    99             else if (m_controlMode == kSpeed)
   100             {
   101                 CANJaguar::SetPID(m_Kp, m_Ki, m_Kd);
   102                 CANJaguar::SetSpeedReference(m_speedRef);
   103                 if (m_speedRef != kSpeedRef_None)
   104                 {
   105                     CANJaguar::ConfigEncoderCodesPerRev(m_encoderLines);
   106                 }
   107             }
   108             else if (m_controlMode == kCurrent)
   109             {
   110                 CANJaguar::SetPID(m_Kp, m_Ki, m_Kd);
   111             }
   112 
   113             if (m_maxOutputVoltage > 0.0)
   114             {
   115                 CANJaguar::ConfigMaxOutputVoltage(m_maxOutputVoltage);
   116             }
   117 
   118             if (m_faultTime > 0.0)
   119             {
   120                 CANJaguar::ConfigFaultTime(m_faultTime);
   121             }
   122 
   123             if (m_neutralMode != kNeutralMode_Jumper)
   124             {
   125                 CANJaguar::ConfigNeutralMode(m_neutralMode);
   126             }
   127 
   128             if (m_fwdLimitPos == 0.0 && m_revLimitPos == 0.0)
   129             {
   130                 CANJaguar::DisableSoftPositionLimits();
   131             }
   132             else
   133             {
   134                 CANJaguar::ConfigSoftPositionLimits(m_fwdLimitPos,
   135                                                     m_revLimitPos);
   136             }
   137 
   138             if (m_voltRampRate > 0.0)
   139             {
   140                 CANJaguar::SetVoltageRampRate(m_voltRampRate);
   141             }
   142 
   143             CANJaguar::EnableControl();
   144         }
   145 
   146         TExitMsg(("=%d", m_fPowerCycled));
   147         return m_fPowerCycled;
   148     }   //CheckPowerCycled
   149 
   150 public:
   151     /**
   152      * Constructor: Create an instance of the CanJag object that inherits
   153      * the CANJaguar class.
   154      *
   155      * @param deviceNumber Specifies the CAN ID for the device.
   156      * @param controlMode Specifies the control mode to set the device to.
   157      */
   158     CanJag(
   159         UINT8 deviceNumber,
   160         ControlMode controlMode = kPercentVbus
   161         ): CANJaguar(deviceNumber, controlMode)
   162          , m_encoderLines(0)
   163          , m_potTurns(0)
   164          , m_faultTime(0.0)
   165          , m_neutralMode(kNeutralMode_Jumper)
   166          , m_fwdLimitPos(0.0)
   167          , m_revLimitPos(0.0)
   168          , m_voltRampRate(0.0)
   169          , m_speedRef(kSpeedRef_None)
   170          , m_posRef(kPosRef_None)
   171          , m_Kp(0.0)
   172          , m_Ki(0.0)
   173          , m_Kd(0.0)
   174          , m_motorValue(0.0)
   175          , m_position(0.0)
   176          , m_speed(0.0)
   177     {
   178         TLevel(INIT);
   179         TEnterMsg(("CanID=%d,mode=%d", deviceNumber, controlMode));
   180 
   181         if (controlMode == kSpeed)
   182         {
   183             m_speedRef = GetSpeedReference();
   184             m_Kp = GetP();
   185             m_Ki = GetI();
   186             m_Kd = GetD();
   187         }
   188         else if (controlMode == kPosition)
   189         {
   190             m_posRef = GetPositionReference();
   191             m_Kp = GetP();
   192             m_Ki = GetI();
   193             m_Kd = GetD();
   194         }
   195         else if (controlMode == kCurrent)
   196         {
   197             m_Kp = GetP();
   198             m_Ki = GetI();
   199             m_Kd = GetD();
   200         }
   201 
   202         m_motorValue = CANJaguar::Get();
   203         m_position = CANJaguar::GetPosition();
   204         m_speed = CANJaguar::GetSpeed();
   205         //
   206         // Clear the power cycled flag.
   207         //
   208         m_fPowerCycled = GetPowerCycled();
   209 
   210 #ifdef _LOGDATA_CANJAG
   211         DataLogger *dataLogger = DataLogger::GetInstance();
   212         char szID[3];
   213         snprintf(szID, sizeof(szID), "%02d", deviceNumber);
   214         dataLogger->AddDataPoint(MOD_NAME, szID, "PowerCycled", "%d",
   215                                  DataInt8, &m_fPowerCycled);
   216         dataLogger->AddDataPoint(MOD_NAME, szID, "MotorValue", "%f",
   217                                  DataFloat, &m_motorValue);
   218         dataLogger->AddDataPoint(MOD_NAME, szID, "MotorPos", "%f",
   219                                  DataDouble, &m_position);
   220         dataLogger->AddDataPoint(MOD_NAME, szID, "MotorSpeed", "%f",
   221                                  DataDouble, &m_speed);
   222 #endif
   223 
   224 #ifdef _CANJAG_PERF
   225         m_setMotorPerfData = NULL;
   226         m_getPosPerfData = NULL;
   227         m_getSpeedPerfData = NULL;
   228 #endif
   229 
   230 
   231         TExit();
   232     }   //CanJag
   233 
   234     /**
   235      * Destructor: Destroy an instance of the CanJag object.
   236      */
   237     virtual
   238     ~CanJag(
   239         void
   240         )
   241     {
   242         TLevel(INIT);
   243         TEnter();
   244         TExit();
   245     }   //~CanJag
   246 
   247     /**
   248      * This function sets the motor power.
   249      *
   250      * @param value Specifies the motor power.
   251      * @param syncGroup Optionally specifies the syncgroup of the motor.
   252      */
   253     void
   254     Set(
   255         float value,
   256         UINT8 syncGroup = 0
   257         )
   258     {
   259         TLevel(API);
   260         TEnterMsg(("value=%f,group=%d", value, syncGroup));
   261 
   262         CheckPowerCycled();
   263         if (value != m_motorValue)
   264         {
   265             //
   266             // Only setting the motor value if it has changed.
   267             //
   268             m_motorValue = value;
   269 #ifdef _CANJAG_PERF
   270             if (m_setMotorPerfData != NULL)
   271             {
   272                 m_setMotorPerfData->StartPerf();
   273             }
   274 #endif
   275             CANJaguar::Set(value, syncGroup);
   276 #ifdef _CANJAG_PERF
   277             if (m_setMotorPerfData != NULL)
   278             {
   279                 m_setMotorPerfData->EndPerf();
   280             }
   281 #endif
   282         }
   283         else if (m_safetyHelper != NULL)
   284         {
   285             //
   286             // Motor value did not change but we still need to feed the
   287             // watchdog.
   288             //
   289             m_safetyHelper->Feed();
   290         }
   291 
   292         TExit();
   293         return;
   294     }   //Set
   295 
   296     /**
   297      * This function sets the reference source device for speed control mode.
   298      *
   299      * @param reference Specifies the reference device.
   300      */
   301     void
   302     SetSpeedReference(
   303         SpeedReference reference
   304         )
   305     {
   306         TLevel(API);
   307         TEnterMsg(("ref=%d", reference));
   308 
   309         m_speedRef = reference;
   310         CANJaguar::SetSpeedReference(reference);
   311 
   312         TExit();
   313         return;
   314     }   //SetSpeedReference
   315 
   316     /**
   317      * This function sets the reference source device for position control mode.
   318      *
   319      * @param reference Specifies the reference device.
   320      */
   321     void
   322     SetPositionReference(
   323         PositionReference reference
   324         )
   325     {
   326         TLevel(API);
   327         TEnterMsg(("ref=%d", reference));
   328 
   329         m_posRef = reference;
   330         CANJaguar::SetPositionReference(reference);
   331 
   332         TExit();
   333         return;
   334     }   //SetPositionReference
   335 
   336     /**
   337      * This function sets the PID constants for the closed loop modes.
   338      *
   339      * @param Kp Specifies the P constant.
   340      * @param Ki SPecifies the I constant.
   341      * @param Kd Specifies the D constant.
   342      */
   343     void
   344     SetPID(
   345         double Kp,
   346         double Ki,
   347         double Kd
   348         )
   349     {
   350         TLevel(API);
   351         TEnterMsg(("Kp=%f,Ki=%f,Kd=%f", Kp, Ki, Kd));
   352 
   353         m_Kp = Kp;
   354         m_Ki = Ki;
   355         m_Kd = Kd;
   356         CANJaguar::SetPID(Kp, Ki, Kd);
   357 
   358         TExit();
   359         return;
   360     }   //SetPID
   361 
   362     /**
   363      * This function sets the maximum voltage change rate.
   364      *
   365      * @param rampRate Specifies the max voltage ramp rate.
   366      */
   367     void
   368     SetVoltageRampRate(
   369         double rampRate
   370         )
   371     {
   372         TLevel(API);
   373         TEnterMsg(("rampRate=%f", rampRate));
   374 
   375         m_voltRampRate = rampRate;
   376         CANJaguar::SetVoltageRampRate(rampRate);
   377 
   378         TExit();
   379         return;
   380     }   //SetVoltageRampRate
   381 
   382     /**
   383      * This function configures the neutral mode.
   384      *
   385      * @param mode Specifies the neutral mode.
   386      */
   387     void
   388     ConfigNeutralMode(
   389         NeutralMode mode
   390         )
   391     {
   392         TLevel(API);
   393         TEnterMsg(("mode=%d", mode));
   394 
   395         m_neutralMode = mode;
   396         CANJaguar::ConfigNeutralMode(mode);
   397 
   398         TExit();
   399         return;
   400     }   //ConfigNeutralMode
   401 
   402     /**
   403      * This function configures the number of encoder lines per revolution.
   404      *
   405      * @param encoderLines Specifies the number of encoder lines per rev.
   406      */
   407     void
   408     ConfigEncoderCodesPerRev(
   409         UINT16 encoderLines
   410         )
   411     {
   412         TLevel(API);
   413         TEnterMsg(("lines=%d", encoderLines));
   414 
   415         m_encoderLines = encoderLines;
   416         CANJaguar::ConfigEncoderCodesPerRev(encoderLines);
   417 
   418         TExit();
   419         return;
   420     }   //ConfigEncoderCodesPerRev
   421 
   422     /**
   423      * This function configures the number of turns of the potentiometer.
   424      *
   425      * @param turns Specifies the number of turns of the potentiometer.
   426      */
   427     void
   428     ConfigPotentiometerTurns(
   429         UINT16 turns
   430         )
   431     {
   432         TLevel(API);
   433         TEnterMsg(("turns=%d", turns));
   434 
   435         m_potTurns = turns;
   436         CANJaguar::ConfigPotentiometerTurns(turns);
   437 
   438         TExit();
   439         return;
   440     }   //ConfigPotentiometerTurns
   441 
   442     /**
   443      * This function configures the forward and reverse position limits.
   444      *
   445      * @param fwdLimitPos Specifies the forward limit position.
   446      * @param revLimitPos Specifies the reverse limit position.
   447      */
   448     void
   449     ConfigSoftPositionLimits(
   450         double fwdLimitPos,
   451         double revLimitPos
   452         )
   453     {
   454         TLevel(API);
   455         TEnterMsg(("fwdLimit=%f,revLimit=%f", fwdLimitPos, revLimitPos));
   456 
   457         m_fwdLimitPos = fwdLimitPos;
   458         m_revLimitPos = revLimitPos;
   459         CANJaguar::ConfigSoftPositionLimits(fwdLimitPos, revLimitPos);
   460 
   461         TExit();
   462         return;
   463     }   //ConfigSoftPositionLimits
   464 
   465     /**
   466      * This function disables soft position limits.
   467      */
   468     void
   469     DisableSoftPositionLimits(
   470         void
   471         )
   472     {
   473         TLevel(API);
   474         TEnter();
   475 
   476         m_fwdLimitPos = 0.0;
   477         m_revLimitPos = 0.0;
   478         CANJaguar::DisableSoftPositionLimits();
   479 
   480         TExit();
   481         return;
   482     }   //DisableSoftPositionLimits
   483 
   484     /**
   485      * This function configures how long the Jaguar waits in the case of a
   486      * fault before resuming operation.
   487      *
   488      * @param faultTime Specifies the fault time.
   489      */
   490     void
   491     ConfigFaultTime(
   492         float faultTime
   493         )
   494     {
   495         TLevel(API);
   496         TEnterMsg(("faultTime=%f", faultTime));
   497 
   498         m_faultTime = faultTime;
   499         CANJaguar::ConfigFaultTime(faultTime);
   500 
   501         TExit();
   502         return;
   503     }   //ConfigFaultTime
   504 
   505     /**
   506      * This function gets the motor position from the Jaguar controller.
   507      *
   508      * @return Returns the motor position.
   509      */
   510     double
   511     GetPosition(
   512         void
   513         )
   514     {
   515         TLevel(API);
   516         TEnter();
   517 
   518 #ifdef _CANJAG_PERF
   519         if (m_getPosPerfData != NULL)
   520         {
   521             m_getPosPerfData->StartPerf();
   522         }
   523 #endif
   524         m_position = CANJaguar::GetPosition();
   525 #ifdef _CANJAG_PERF
   526         if (m_getPosPerfData != NULL)
   527         {
   528             m_getPosPerfData->EndPerf();
   529         }
   530 #endif
   531 
   532         TExitMsg(("=%f", m_position));
   533         return m_position;
   534     }   //GetPosition
   535 
   536     /**
   537      * This function gets the motor speed from the Jaguar controller.
   538      *
   539      * @return Returns the motor speed.
   540      */
   541     double
   542     GetSpeed(
   543         void
   544         )
   545     {
   546         TLevel(API);
   547         TEnter();
   548 
   549 #ifdef _CANJAG_PERF
   550         if (m_getSpeedPerfData != NULL)
   551         {
   552             m_getSpeedPerfData->StartPerf();
   553         }
   554 #endif
   555         m_speed = CANJaguar::GetSpeed();
   556 #ifdef _CANJAG_PERF
   557         if (m_getSpeedPerfData != NULL)
   558         {
   559             m_getSpeedPerfData->EndPerf();
   560         }
   561 #endif
   562 
   563         TExitMsg(("=%f", m_speed));
   564         return m_speed;
   565     }   //GetSpeed
   566 
   567 #ifdef _CANJAG_PERF
   568     /**
   569      * This function sets up the various perfdata objects.
   570      *
   571      * @param setMotorPerfData Points to the perfdata object to collect
   572      *        Set() performance.
   573      * @param getPosPerfData Points to the perfdata object to collect
   574      *        GetPosition() performance.
   575      * @param getSpeedPerfData Points to the perfdata object to collect
   576      *        GetSpeed() performance.
   577      */
   578     void
   579     SetPerfData(
   580         PerfData *setMotorPerfData,
   581         PerfData *getPosPerfData,
   582         PerfData *getSpeedPerfData
   583         )
   584     {
   585         TLevel(API);
   586         TEnter();
   587  
   588         m_setMotorPerfData = setMotorPerfData;
   589         m_getPosPerfData = getPosPerfData;
   590         m_getSpeedPerfData = getSpeedPerfData;
   591 
   592         TExit();
   593         return;
   594     }   //SetPerfData
   595 #endif
   596 
   597 };  //class CanJag
   598 
   599 #endif  //ifndef _CANJAG_H