Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

PhysicalMomentumWheel.cpp

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////////////////////////
00002 /*! \file PhysicalMomentumWheel.cpp
00003 *  \brief Implementation of the PhysicalMomentumWheel class
00004 *  \author $Author: jayhawk_hokie $
00005 *  \version $Revision: 1.44 $
00006 *  \date    $Date: 2007/08/31 15:48:03 $
00007 *//////////////////////////////////////////////////////////////////////////////////////////////////
00008 /*! 
00009 */
00010 //////////////////////////////////////////////////////////////////////////////////////////////////
00011 
00012 
00013 #include "PhysicalMomentumWheel.h"
00014 
00015 //////////////////////////////////////////////////////////////////////
00016 // Construction/Destruction
00017 //////////////////////////////////////////////////////////////////////
00018 
00019 PhysicalMomentumWheel::PhysicalMomentumWheel( )
00020 {
00021         pthread_mutex_init( &m_Mutex, NULL );
00022 
00023 
00024         m_fd = -1;
00025         m_BiasFlag = 0;
00026         m_CurrentWheelSpeed = 0.0; // [rad/s]
00027 
00028         m_MinVolts = 15; // [V]
00029         m_MaxAmps  = 24; // [A]
00030 
00031         //With WheelHistory far from implementation, members vars are used to store last state info
00032 
00033         // PID Controller Parameters
00034         LAST_VEL = 0.0;
00035         LAST_TOR = 0.0;
00036         LAST_ERR = 0.0;
00037         LAST_VOLT = 25.0; // [V]
00038 
00039         // Torque Controller Parameters
00040         m_TorqueControlFlag = 1;
00041         m_TorqueControllerDeltaTime = 0.4; // [s]
00042         m_TorqueControllerTorqueGain = 1; 
00043         m_TorqueControllerNegativeTimeGain = 0.5; // [s]
00044         m_TorqueControllerSteadyStateGain = 1.0; // [rad/s]
00045         m_TorqueControllerDesiredWheelSpeedFlag = 0;
00046         
00047         m_exitConditionTorque = 1;
00048         
00049         //Set SmartMotor 3430 physical limits
00050         m_MaxWheelTorque = 1023;
00051 
00052         m_MinWheelTorque = -m_MaxWheelTorque;
00053         m_MaxTorqueStep = 700;
00054 
00055         // Wheel Speed Coefficients
00056         m_Coefficients1.initialize(4);
00057         m_Coefficients2.initialize(3);
00058         m_Coefficients3.initialize(3);
00059         m_Coefficients4.initialize(4);
00060         
00061         m_exitConditionSpeed = 1;
00062 
00063 }
00064 
00065 PhysicalMomentumWheel::~PhysicalMomentumWheel( )
00066 {
00067 
00068         Deinitialize();
00069 
00070 }
00071 
00072 //////////////////////////////////////////////////////////////////////
00073 //  Facilitators
00074 /////////////////////////////////////////////////////////////////////
00075 
00076 
00077 int PhysicalMomentumWheel::Initialize( )
00078 {
00079         //pthread_mutex_lock( &m_Mutex );
00080         
00081         char *stringPort;
00082         stringPort = (char *)malloc(80);
00083         
00084         if ( m_fd < 0 ) // g_fd has NOT been set yet, then init the daisychain
00085         {
00086                 sprintf(stringPort,"%s",m_DaisyChainPort.c_str());
00087                 
00088                 init_serial( stringPort, B9600, &m_fd );
00089 
00090                 Reset( ); // Reset Wheel Motor settings
00091 
00092                 ChangeBaud( ); // Change Baud Rate      
00093         
00094                 close( m_fd );
00095                 
00096                 init_serial( stringPort, B19200, &m_fd );
00097                 
00098                 EchoOff( ); // Set ECHO function to off 
00099          
00100                 EnableTorqueMode( ); // Enable torque mode for the wheel motor
00101         } 
00102 
00103         //pthread_mutex_unlock( &m_Mutex );
00104 
00105         if( m_BiasFlag )
00106         {
00107                 m_DesiredWheelSpeed = m_BiasSpeed ;
00108                 CommandWheelSpeed( );
00109         }
00110           
00111         // Start wheel Query
00112         cerr << "Start Speed Query for Wheel" << endl;
00113         StartSpeedQuery( );
00114         usleep( 500000 ); // necessary for wheels to get first speed.
00115 
00116         cerr << "Wheel Initialized: " << m_WheelName << endl;
00117 
00118         return( 0 );
00119 }
00120 
00121 
00122 int PhysicalMomentumWheel::Deinitialize( ) 
00123 {
00124         cerr << "\n\nDEINITIALIZING WHEEL: " << m_WheelName << endl;
00125 
00126         
00127         if ( !m_TorqueControlFlag )
00128         {
00129                 cerr << "Stop Torque Controller" << endl;
00130                 StopTorqueController( );
00131         }
00132 
00133         cerr << "Stop Wheel " << endl;
00134         Stop( );
00135 
00136         cerr << "Stop Speed Query" << endl;
00137         StopSpeedQuery( );
00138 
00139         cerr << "Deallocating memory from mutex" << endl;
00140         pthread_mutex_destroy( &m_Mutex );
00141 
00142         cerr << "Serial Port Closing:\n";
00143         close( m_fd );
00144         return( 0 );
00145 }
00146 
00147 
00148 int PhysicalMomentumWheel::Reset( )
00149 {
00150         char *command;
00151         command = new char[80];
00152         sprintf( command, "Z\n\n" );
00153         pthread_mutex_lock(&m_Mutex);
00154                 say( m_fd, command );
00155                 cerr << "\nRESET MOMENTUM WHEEL SETTINGS for wheel: " << m_WheelName << endl;
00156         pthread_mutex_unlock(&m_Mutex);
00157         // pause 1.5 seconds
00158         usleep(1500000);
00159         delete command;
00160         return( 0 );
00161 }
00162 
00163 int PhysicalMomentumWheel::ChangeBaud( )
00164 {
00165         char *posString = new char[80];
00166         char *command;
00167         command = new char[80];
00168         sprintf( command, "BAUD19200\n\n" );
00169         pthread_mutex_lock(&m_Mutex);
00170                 say( m_fd, command );
00171                 cerr << "RESET BAUD to 19200: " << m_WheelName << endl;
00172                 hear( m_fd, posString, 15, 0, 50000, '\r' );
00173         pthread_mutex_unlock(&m_Mutex);
00174         // pause 1.5 seconds
00175         usleep(1500000);
00176         delete command;
00177         delete posString;
00178         return( 0 );
00179 }
00180 
00181 int PhysicalMomentumWheel::EchoOn( )
00182 {
00183         char *command;
00184         command = new char[80];
00185         sprintf( command, "ECHO\n\n" );
00186         pthread_mutex_lock(&m_Mutex);
00187                 say( m_fd, command );
00188                 cerr << "SET ECHO ON for wheel: " << m_WheelName  << endl;
00189         pthread_mutex_unlock(&m_Mutex);
00190         // pause 1.5 seconds
00191         usleep(1500000);
00192         delete command;
00193         return( 0 );
00194 }
00195 
00196 int PhysicalMomentumWheel::EchoOff( )
00197 {
00198         char *command;
00199         command = new char[80];
00200         sprintf( command, "ECHO_OFF\n\n" );
00201         pthread_mutex_lock(&m_Mutex);
00202                 say( m_fd, command );
00203                 cerr << "SET ECHO OFF for wheel: " << m_WheelName  << endl;
00204         pthread_mutex_unlock(&m_Mutex);
00205         // pause 1.5 seconds
00206         usleep(1500000);
00207         delete command;
00208         return( 0 );
00209 }
00210 
00211 int PhysicalMomentumWheel::EnableTorqueMode( )
00212 {
00213         char *command;
00214         command = new char[80];
00215         sprintf( command, "MT\n\n" );
00216         pthread_mutex_lock(&m_Mutex);
00217                 say( m_fd, command );
00218                 cerr << "ENABLE TORQUE MODE for wheel: " << m_WheelName  << endl;
00219         pthread_mutex_unlock(&m_Mutex);
00220         // pause 1.5 seconds
00221         usleep(1500000);
00222         delete command;
00223         return( 0 );
00224 }
00225 
00226 int PhysicalMomentumWheel::TorqueCommand( double _power )
00227 {
00228         static char *torqueCommand = new char[80];
00229         sprintf( torqueCommand, "T%f\n\n", _power );
00230         pthread_mutex_lock(&m_Mutex);
00231                 say(m_fd, torqueCommand);
00232         pthread_mutex_unlock(&m_Mutex);
00233         return( 0 );
00234 }
00235 
00236 
00237 int PhysicalMomentumWheel::Stop( )
00238 {
00239         pthread_mutex_unlock(&m_Mutex); // encase mutex lock has been activated in another function
00240         Reset( );
00241         return( 0 );
00242 }
00243 
00244 void PhysicalMomentumWheel::StartSpeedQuery( )
00245 {
00246         pthread_create( &m_SpeedThreadID, NULL, QueryWheelSpeed, (void*) this );
00247 }
00248 
00249 void* QueryWheelSpeed( void* arg )
00250 {
00251         PhysicalMomentumWheel *wheel = (PhysicalMomentumWheel*) arg;
00252         double pos1 = 0.0;
00253         double pos2 = 0.0;
00254         double timeStamp1 = 0.0;
00255         double timeStamp2 = 0.0;
00256         char *posString = new char[80];
00257         char *posString2 = new char[80];
00258         double velocity = 0.0 ;
00259         int readdelay = 100000; // 1000000
00260         char *RPCommand = new char[80];
00261 
00262         
00263         // First Point
00264         
00265         //clear serial port buffer
00266         //char* clear = new char[80];
00267         //begin commanding and reading
00268         sprintf(RPCommand, "RP\n");
00269 
00270         // Lock Reaction Wheel Parameters
00271         pthread_mutex_lock(&wheel->m_Mutex);
00272 
00273                 //while( !hear( wheel->m_fd, clear, 79, 0, 3333, 'c' ));
00274 
00275                 double timeA = Now( );
00276                 hear( wheel->m_fd, posString, 15, 0, 50000, '\r' );
00277                 double timeB = Now( );
00278                 timeStamp1 = (timeB + timeA)/2;
00279                 //say(wheel->m_fd, RPCommand);
00280                 //timeStamp1 = Now();
00281                 //hear( wheel->m_fd, posString, 15, 0, 50000, '\r' );
00282         // Unlock Reaction Wheel Parameters
00283         pthread_mutex_unlock(&wheel->m_Mutex);
00284         pos1 = atoi(posString);
00285 
00286         int exit = 1;   
00287 
00288         while( exit )
00289         {
00290                 pthread_testcancel();
00291 
00292                 //clear serial port buffer
00293                 //char* clear = new char[80];
00294                 //begin commanding and reading
00295                 sprintf(RPCommand, "RP\n");
00296                 
00297                 usleep(readdelay);
00298 /*              
00299         // Lock Reaction Wheel Parameters
00300         pthread_mutex_lock(&wheel->m_Mutex);
00301 
00302                 //while( !hear( wheel->m_fd, clear, 79, 0, 3333, 'c' ));
00303 
00304                 say(wheel->m_fd, RPCommand);
00305                 
00306                 double timeA = Now( );
00307                 hear( wheel->m_fd, posString, 15, 0, 50000, '\r' );
00308                 double timeB = Now( );
00309                 timeStamp1 = (timeB + timeA)/2;
00310                 //timeStamp1 = timeB;
00311         // Unlock Reaction Wheel Parameters
00312         //pthread_mutex_unlock(&wheel->m_Mutex);
00313         
00314                 pos1 = atoi(posString);
00315 
00316         pthread_testcancel( );
00317 
00318         usleep( 100000 );
00319 */              
00320                 //position2
00321                 // Lock Reaction Wheel Parameters
00322                 pthread_mutex_lock(&wheel->m_Mutex);
00323 
00324                         say(wheel->m_fd, RPCommand);
00325                 
00326                         double timeC = Now( );
00327                         hear(wheel->m_fd, posString2, 15, 0, 50000, '\r');
00328                         double timeD = Now( );
00329                         timeStamp2 = (timeD + timeC )/2;
00330                         //timeStamp2 =  timeC;
00331                 // Unlock Reaction Wheel Parameters
00332                 pthread_mutex_unlock(&wheel->m_Mutex);
00333         
00334                 pos2 = atoi(posString2);
00335                 
00336                 // Negative sign for correct rotation direction. Right Hand Rule -> along shaft away from motor. 
00337                 velocity = -( (pos2 - pos1) /( timeStamp2 - timeStamp1 ))*2*3.14159/4000.0; // rad/sec => 2pi rad/4000 ct
00338                 //velocity = -( (pos2 - pos1) /( 20000 ))*2*3.14159/4000.0; // rad/sec => 2pi rad/4000 ct
00339 
00340                 //timeStamp2 = Now( );
00341 
00342                 pthread_mutex_lock(&wheel->m_Mutex);
00343                         wheel->m_CurrentWheelSpeed = velocity; // (rad/s)
00344                         wheel->m_VelocityTime = timeStamp2; // (s)      
00345                 pthread_mutex_unlock(&wheel->m_Mutex);
00346                 
00347                 // Update to use for next measurement
00348                 pos1 = pos2;
00349                 timeStamp1 = timeStamp2;                
00350                 
00351                 pthread_testcancel( );
00352                 
00353                 // Lock Reaction Wheel Parameters
00354                 pthread_mutex_lock(&wheel->m_Mutex);
00355                         exit = wheel->m_exitConditionSpeed;
00356                 // Unlock Reaction Wheel Parameters
00357                 pthread_mutex_unlock(&wheel->m_Mutex);
00358 
00359         }
00360 
00361         return arg;
00362 }
00363 
00364 void PhysicalMomentumWheel::StopSpeedQuery( )
00365 {
00366         pthread_mutex_lock( &m_Mutex );
00367                 m_exitConditionSpeed = 0;
00368         pthread_mutex_unlock( &m_Mutex );
00369                 
00370         pthread_join( m_SpeedThreadID, NULL );
00371 }
00372 
00373 
00374 void PhysicalMomentumWheel::CommandWheelTorque( double _wheelTorque )
00375 {
00376         if( m_TorqueControlFlag )
00377         {
00378                 StartTorqueController( );
00379                 m_TorqueControlFlag = 0;
00380         }
00381         // Lock Reaction Wheel Parameters
00382         pthread_mutex_lock(&m_Mutex);
00383                 m_DesiredWheelTorque = _wheelTorque;
00384         // Unlock Reaction Wheel Parameters
00385         pthread_mutex_unlock(&m_Mutex);
00386 
00387 }
00388 
00389 void PhysicalMomentumWheel::StartTorqueController()
00390 {
00391         //pthread_create(&m_TorqueThreadID, NULL, RunTorqueController, (void*) this);
00392         pthread_create(&m_TorqueThreadID, NULL, RunTorqueControllerRev, (void*) this);
00393 }
00394 
00395 
00396 void* RunTorqueControllerRev( void* arg )
00397 {
00398         // Create PhysicalMomentumWheel Object and get parameters from arg
00399         PhysicalMomentumWheel *reactionWheel = (PhysicalMomentumWheel*) arg;
00400 
00401         int CommandWheelSpeedFlag = 0;
00402         
00403         // Determine Steady State Coefficient [~]
00404         /* equation not good enough
00405         double Constant  = -0.000000000000006*pow( reactionWheel->m_TorqueControllerDeltaTime, 10 )
00406                         + 0.000000000002074*pow( reactionWheel->m_TorqueControllerDeltaTime , 9 ) 
00407                         - 0.0000000002887*pow( reactionWheel->m_TorqueControllerDeltaTime , 8 ) 
00408                         + 0.00000002271*pow( reactionWheel->m_TorqueControllerDeltaTime , 7 ) 
00409                         - 0.000001111*pow( reactionWheel->m_TorqueControllerDeltaTime , 6 ) 
00410                         + 0.000003512*pow( reactionWheel->m_TorqueControllerDeltaTime , 5 ) 
00411                         - 0.0007216*pow(  reactionWheel->m_TorqueControllerDeltaTime, 4 ) 
00412                         + 0.009515*pow(  reactionWheel->m_TorqueControllerDeltaTime, 3 ) 
00413                         - 0.07825*pow(  reactionWheel->m_TorqueControllerDeltaTime, 2 ) 
00414                         + 0.3839* reactionWheel->m_TorqueControllerDeltaTime + 0.02609;
00415         */
00416         double Constant = 0;
00417         double ConstantPositive = 0.109; // for increasing wheel speed.
00418         //double ConstantNegative = 0.05; // didn't work! for deacreasing wheel speed. Derived from looking at steady state condition.
00419         double ConstantNegative = 0.109; // for deacreasing wheel speed. set the same as positive value.
00420         //Constant = 0.04406469;
00421         double time1=0;
00422         double time2=0;
00423         double desiredTorque=0.0;
00424 
00425         double steadyStateWheelSpeed = 0.0;
00426 
00427         double reduceWheelSpeedTimeGain = 0.0; 
00428         //double reduceWheelSpeedGain = 0.15; 
00429         double reduceWheelSpeedGain = 0.25; 
00430         double delayTime = 0.0;
00431         int condition = 0;
00432 
00433         int exit = 1;
00434 
00435         // The torque controller will run until the thread is terminated with a deinitialization call.
00436         while( exit )
00437         {
00438                         
00439                 time1 = Now( );
00440                 
00441                 reduceWheelSpeedTimeGain = 1; 
00442                 
00443                 // Lock Reaction Wheel Parameters
00444                 pthread_mutex_lock( &reactionWheel->m_Mutex );
00445                         // Determine Final Wheel Speed [rad/s].  Note negative will spin the reaction wheels in the opposite direction to provide the correct +/- torque.
00446                         
00447                         desiredTorque = reactionWheel->m_DesiredWheelTorque; 
00448                         
00449                         if ( reactionWheel->m_DesiredWheelTorque )
00450                         {
00451                                 double finalWheelSpeed = reactionWheel->m_CurrentWheelSpeed 
00452                                         + ( reactionWheel->m_TorqueControllerTorqueGain*(-reactionWheel->m_DesiredWheelTorque) )
00453                                         * reactionWheel->m_TorqueControllerDeltaTime/reactionWheel->m_AxialInertia;  
00454                                 // Determine Steady State Wheel Speed [rad/s]
00455                                 // This might produce jumpy results.
00456                                 if ( finalWheelSpeed < reactionWheel->m_CurrentWheelSpeed && finalWheelSpeed >= 0 && reactionWheel->m_CurrentWheelSpeed >=0 )
00457                                 {
00458                                         condition = 1;
00459                                 }
00460                                 else if ( finalWheelSpeed > reactionWheel->m_CurrentWheelSpeed && finalWheelSpeed <= 0 && reactionWheel->m_CurrentWheelSpeed <= 0 )
00461                                 {
00462                                         condition = 1;
00463                                 }
00464                                 else
00465                                 {
00466                                         condition = 0;
00467                                 }
00468                                 if ( condition )
00469                                 {
00470                                         //cerr << "Decrease Wheel Speed: " << finalWheelSpeed << " Current= " << reactionWheel->m_CurrentWheelSpeed << endl; 
00471                                         Constant = ConstantNegative; // This should act as a brake for the wheel.
00472                                         //steadyStateWheelSpeed = reduceWheelSpeedGain*reactionWheel->m_TorqueControllerSteadyStateGain
00473                                         //      * ( finalWheelSpeed + ( Constant - 1 )*reactionWheel->m_CurrentWheelSpeed )/Constant; 
00474                                         steadyStateWheelSpeed = reduceWheelSpeedGain*reactionWheel->m_TorqueControllerSteadyStateGain
00475                                                 * ( finalWheelSpeed - reactionWheel->m_CurrentWheelSpeed )/Constant; 
00476                                         reduceWheelSpeedTimeGain = 0.2; // experimentally determined 
00477                                 }
00478                                 else
00479                                 {
00480                                         Constant = ConstantPositive;
00481                                         steadyStateWheelSpeed = reactionWheel->m_TorqueControllerSteadyStateGain
00482                                                 * ( finalWheelSpeed + ( Constant - 1 )*reactionWheel->m_CurrentWheelSpeed )/Constant; 
00483                                 }
00484                                 // Set Reaction Wheel Speed.
00485                                 reactionWheel->m_DesiredWheelSpeed = steadyStateWheelSpeed;
00486                                 // Reset Control Torque to Zero
00487                                 //desiredTorque = reactionWheel->m_DesiredWheelTorque; 
00488                                 reactionWheel->m_DesiredWheelTorque = 0; 
00489                                 reactionWheel->m_TorqueControllerDesiredWheelSpeedFlag = 1; 
00490                                 CommandWheelSpeedFlag = 1;
00491                         }
00492                         else
00493                         {
00494                                 if( reactionWheel->m_TorqueControllerDesiredWheelSpeedFlag )
00495                                 {
00496                                         reactionWheel->m_DesiredWheelSpeed = reactionWheel->m_CurrentWheelSpeed;
00497                                         reactionWheel->m_TorqueControllerDesiredWheelSpeedFlag = 0;
00498                                         CommandWheelSpeedFlag = 1;
00499                                 }
00500                                 else
00501                                 {
00502                                         CommandWheelSpeedFlag = 0;
00503                                 }
00504                         }
00505 
00506                         delayTime = reactionWheel->m_TorqueControllerDeltaTime*1000000*reduceWheelSpeedTimeGain;
00507 
00508                 // Unlock Reaction Wheel Parameters
00509                 pthread_mutex_unlock( &reactionWheel->m_Mutex );
00510                 
00511                 
00512                 // Lock Reaction Wheel Parameters
00513                 pthread_mutex_lock( &reactionWheel->m_Mutex );
00514                         exit = reactionWheel->m_exitConditionTorque;
00515                 // Unlock Reaction Wheel Parameters
00516                 pthread_mutex_unlock( &reactionWheel->m_Mutex );
00517                 
00518                 time2 = time1;
00519                 //cerr << "delta Time = " << time1-time2 << endl;
00520                 
00521                 if( CommandWheelSpeedFlag )
00522                 {
00523                         // Determine Power Setting and Send to Reaction Wheel Motor
00524                         reactionWheel->CommandWheelSpeed( );
00525                 }
00526                 
00527                 
00528                 usleep( int( delayTime ) );
00529         } 
00530 
00531         return arg;
00532 }
00533 
00534 /*
00535         double wheelAxialInertia; // wheel axial inertia (kg/m^2)
00536         wheel->GetAxialInertia( wheelAxialInertia );
00537 
00538         double initialWheelSpeed = 0; // (rad/s)
00539 
00540         double desiredWheelSpeed = 0; // (rad/s)
00541 
00542         double steadyStateWheelSpeed = 0; // (rad/s)
00543 
00544         double augmentedSteadyStateWheelSpeed = 0; // (rad/s)
00545 
00546         double desiredTorque = 0; // (N-m)
00547 
00548         double deltaTime = 1.0;//0.5; // (s)
00549 
00550 
00551         int negflag = 1;
00552 
00553         double torqueGain = 1;  // proportional gain (to tune function to supply torques closer to actual N-m)
00554         
00555         // Proportional Torque Gain (to tune function to supply torques closer to actual N-m)
00556         double m_TorqueControllerTorqueGain;
00557 
00558         // Negative Time Gain
00559         double m_TorqueControllerNegativeTimeGain;  
00560 
00561 
00562         double negativeTimeGain = 0.5;  //negative time gain
00563 
00564         double augmentationGain = 1.12; //positive augmentation gain
00565 
00566         double steadyStateGain = 7; //positive steady state (rad/s)
00567 
00568         double minimumTorque = 0.003; //torque threshold
00569 
00570         while( 1 ) // endless loop
00571         {
00572                 pthread_testcancel();
00573 
00574                 pthread_mutex_lock( &wheel->m_Mutex );
00575 
00576                         desiredTorque = torqueGain * wheel->m_DesiredWheelTorque; // from controller
00577 
00578                         initialWheelSpeed = - wheel->m_CurrentWheelSpeed;
00579 
00580                         // not smart method for limiting wheel speed!
00581                         if( fabs( initialWheelSpeed ) > 200 ) // float absolute of w1, (rad/s) (~1900 rad/s)
00582                         {
00583                                 initialWheelSpeed = wheel->LAST_VEL; // (rad/s)
00584                         }
00585                 
00586                 pthread_mutex_unlock( &wheel->m_Mutex );
00587                 
00588                 pthread_testcancel();
00589                 
00590                 desiredWheelSpeed = initialWheelSpeed + ( desiredTorque ) * deltaTime / ( wheelAxialInertia );
00591 
00592                 steadyStateWheelSpeed = ( desiredWheelSpeed + ( Constant - 1 ) * initialWheelSpeed ) / Constant;
00593 
00594                 // Command Logic for wheel angular rates.
00595                 if( fabs( desiredTorque ) < minimumTorque ) // don't do anything
00596                 {
00597                         usleep( (int) ( deltaTime*1000000 ) );
00598                 } 
00599                 else if(negflag)
00600                 {
00601                         augmentedSteadyStateWheelSpeed = steadyStateWheelSpeed*augmentationGain + steadyStateWheelSpeed*steadyStateGain/fabs( steadyStateWheelSpeed );
00602                         wheel->SetWheelSpeed( augmentedSteadyStateWheelSpeed );
00603                         wheel->CommandWheelSpeed( );
00604                         usleep( (int) (deltaTime*1000000) );
00605                 } 
00606                 else // what is this?
00607                 {
00608                         usleep((int) ( deltaTime*1000000 - deltaTime*1000000*fabs( desiredTorque )*negativeTimeGain ) );
00609                 }
00610                 
00611                 negflag = 1;
00612 
00613                 pthread_mutex_lock(&wheel->m_Mutex);
00614 
00615                         wheel->LAST_VEL = initialWheelSpeed;
00616 
00617                 pthread_mutex_unlock( &wheel->m_Mutex );
00618 
00619                 pthread_testcancel();
00620         }
00621 */
00622         //return ;
00623 //}
00624 
00625 
00626 /*! \brief Determine reaction wheel speed to provide the desired torque requested from controller.
00627   * 
00628   * @param void* arg
00629   */
00630 void* RunTorqueController(void* arg)
00631 {
00632         PhysicalMomentumWheel *wheel = (PhysicalMomentumWheel*) arg;
00633 
00634         double wheelAxialInertia; // wheel axial inertia (kg/m^2)
00635         wheel->GetAxialInertia( wheelAxialInertia );
00636 
00637         double w1;
00638 
00639         double w2;
00640 
00641         double wss;
00642 
00643         double desiredTorque = 0;
00644 
00645         double deltat = 0.5;
00646 
00647         double C  = 0.000001906374*pow(deltat,5) - 0.00012550397*pow(deltat,4) + 0.0032678612*pow(deltat,3) 
00648                         - 0.043053012550397*pow(deltat,4) + 0.0032678612*pow(deltat,3) - 0.0957*pow(deltat,2) 
00649                         + 0.3024019105*deltat + 0.00429944309;
00650 
00651         int negflag = 1;
00652 
00653         double k = 1;  // proportional gain (to tune function to supply torques closer to actual N-m)
00654 
00655         double knt = 0.5;  //negative time gain
00656 
00657         double kpa = 1.12; //positive augmentation gain
00658 
00659         double kps = 7; //positive steady state
00660 
00661         double minT = 0.03; //torque threshold
00662 
00663         while( 1 ) // endless loop
00664         {
00665                 pthread_testcancel();
00666 
00667                 pthread_mutex_lock( &wheel->m_Mutex );
00668 
00669                 desiredTorque = k * wheel->m_DesiredWheelTorque; // from controller
00670 
00671                 // why negative?
00672                 w1 = - wheel->m_CurrentWheelSpeed;
00673 
00674                 cout << "w1: " << w1 << endl;
00675 
00676                 if( fabs( w1 ) > 200 ) // float absolute of w1, (rad/s)
00677                 {
00678                         w1 = wheel->LAST_VEL; // (rad/s)
00679                 }
00680                 
00681                 cout << "w1 after check: " << w1 << endl;
00682 
00683                 pthread_mutex_unlock( &wheel->m_Mutex );
00684                 
00685                 //k = fabs(desTor)/.3; // proportional gain (to tune function to supply torques closer to actual N-m)
00686                 //desTor = k*desTor;
00687                 
00688                 // crude integration
00689                 w2 = w1 + ( desiredTorque ) * deltat / ( wheelAxialInertia );
00690 
00691                 cout << "w2: " << w2 << endl;
00692         
00693                 wss = ( w2 + ( C - 1 ) * w1 ) / C;
00694 
00695                 cout << "wss: " << wss << endl;
00696                 
00697         //      pthread_testcancel();
00698 
00699         /*
00700                 if(fabs(wss)<fabs(w1) && wss*w1 > 0){
00701                         deltat = -0.0844/(-0.1744+(desTor/(I*-(w1))));
00702                         w2 = w1 + (desTor)*deltat/I;
00703                         //sleept = 310000;
00704                         wheel->CommandSystemTorque(-w1/fabs(w1)*0.0018);
00705                 }
00706         */
00707 
00708         /*
00709                 if( fabs( w2 ) < fabs( w1 ) && fabs( desiredTorque ) > ( k*minT ) )
00710                 {
00711                         wheel->CommandSystemTorque( -w1 / fabs(w1) * 0.0018 );
00712                         usleep( (int) ( deltat * 1000000 * fabs(desiredTorque) * knt ) );
00713                         negflag = 0;
00714 
00715                         cout << " Inside CommandSystemTorque loop " << endl;
00716 
00717                         //of << wheel->m_DaisyChainPort[3] << " " << desTor << " " << wss << " " << w2 << " " << w1 << endl;
00718                 }
00719         */
00720         //      pthread_testcancel();
00721 
00722                 //of << wheel->m_DaisyChainPort[3] << " " << desTor << " " << wss << " " << w2 << " " << w1 << " " << negflag << endl;
00723 
00724                 // what the hell?
00725                 //wheel->CommandWheelSpeed( wss );//+20*wss/fabs(wss));
00726                 
00727                 //cout << "command wss " << endl;
00728                 
00729                 // Command Logic for wheel angular rates.
00730                 if( fabs( desiredTorque ) < minT) // don't do anything
00731                 {
00732                         usleep((int) (deltat*1000000));
00733                 } 
00734                 else if(negflag)
00735                 {
00736                         wheel->SetWheelSpeed( wss*kpa + kps*wss/fabs(wss) );
00737                         wheel->CommandWheelSpeed( );
00738                         usleep((int) (deltat*1000000));
00739                 } 
00740                 else // what is this?
00741                 {
00742                         usleep((int) (deltat*1000000 - deltat*1000000*fabs(desiredTorque)*knt));
00743                 }
00744                 
00745                 // what the hell part 2
00746                 //wheel->CommandWheelSpeed(w2);
00747                 //cout << "command w2 " << endl;
00748 
00749                 negflag = 1;
00750 
00751                 pthread_mutex_lock(&wheel->m_Mutex);
00752 
00753                 // doesn't seem to make sense
00754                 wheel->LAST_VEL = w1;
00755 
00756                 pthread_mutex_unlock(&wheel->m_Mutex);
00757 
00758                 pthread_testcancel();
00759         }
00760         return NULL;
00761 }
00762 
00763 void PhysicalMomentumWheel::StopTorqueController( )
00764 {
00765         pthread_mutex_lock( &m_Mutex );
00766                 m_exitConditionTorque = 0;
00767         pthread_mutex_unlock( &m_Mutex );
00768         
00769         pthread_join( m_TorqueThreadID, NULL );
00770 }
00771 
00772 void PhysicalMomentumWheel::SetWheelSpeed( double desiredWheelSpeed )
00773 {
00774         pthread_mutex_lock( &m_Mutex );
00775                 m_DesiredWheelSpeed = desiredWheelSpeed;
00776         pthread_mutex_unlock( &m_Mutex );
00777 }
00778 
00779 void PhysicalMomentumWheel::CommandWheelSpeed( )
00780 {
00781 
00782         // Before applying wheel command check Voltage and Amps
00783         double volts;
00784         double amps;
00785         
00786         volts = GetVolts( );
00787         amps = GetAmps( );
00788         
00789         if( fabs(volts) < m_MinVolts )
00790         {
00791                 cerr << "WARNING: " << m_WheelName << " Voltage is LOW! Voltage = " << volts << " .... Rechecking Voltage " << endl;
00792                 volts = GetVolts( );
00793                 if( fabs( volts ) < m_MinVolts )
00794                 {
00795                         cerr << "Warning 2nd Check: Voltage Too LOW! Voltage = "<< volts << " .... No Command Sent to Motor " << m_WheelName  << endl;
00796                         return;
00797                 }
00798         }
00799         else if( fabs( amps ) > m_MaxAmps )
00800         {
00801                 cerr << "WARNING: " << m_WheelName << " Current is High! Amps = " << amps << " .... Rechecking Current " << endl;
00802                 amps = GetAmps( );
00803                 if( fabs(amps) > m_MaxAmps )
00804                 {
00805                         cerr << "Warning 2nd Check: Current Too HIGH! Amps = "<< amps << " .... No Command Sent to Motor " << m_WheelName  << endl;
00806                         return;
00807                 }
00808         }
00809         else
00810         { }
00811 
00812         // values derived for Z wheel motor.
00813         double powerCommanded = 0;
00814         double scaledWheelRate = m_DesiredWheelSpeed / volts; // [rad/s/volt]
00815 /*
00816         if ( scaledWheelRate >= -7.6 && scaledWheelRate < -1.2 )
00817         {
00818                 powerCommanded = 0.3085*pow( scaledWheelRate, 3 ) + 4.3691*pow( scaledWheelRate, 2 ) - 94.8364*scaledWheelRate - 15.6830;
00819         }
00820         else if ( scaledWheelRate >= -1.2 && scaledWheelRate < 0 )
00821         {
00822                 powerCommanded = 25.9997*pow( scaledWheelRate, 2 ) - 31.1477*scaledWheelRate + 25.968;
00823         }
00824         else if ( scaledWheelRate >= 0 && scaledWheelRate<= 1.2 )
00825         {
00826                 powerCommanded = - 26.174*pow( scaledWheelRate, 2 ) - 31.1465*scaledWheelRate - 25.9364;
00827         }
00828         else if ( scaledWheelRate > 1.2 && scaledWheelRate <= 7.6 )
00829         {
00830                 powerCommanded = 0.1015*pow( scaledWheelRate, 3 ) - 1.9227*pow( scaledWheelRate, 2 ) - 103.3392*scaledWheelRate + 24.3888;
00831         }
00832         else
00833         {
00834                 // The Motor will maintain the previous voltage
00835                 cerr << "\nWARNING: OUTSIDE POWER COMMANDED to MOTOR BOUNDS. No Power setting sent to Wheel Motor.  Wheel: " << m_WheelName 
00836                 << "   Scaled Wheel Rate = " << scaledWheelRate << endl << endl;
00837                 return; 
00838         }
00839 */
00840 
00841         if ( scaledWheelRate >= -7.6 && scaledWheelRate < -1.2 )
00842         {
00843                 powerCommanded = (m_Coefficients1)(1)*pow( scaledWheelRate, 3 ) + (m_Coefficients1)(2)*pow( scaledWheelRate, 2 ) + (m_Coefficients1)(3)*scaledWheelRate + (m_Coefficients1)(4);
00844         }
00845         else if ( scaledWheelRate >= -1.2 && scaledWheelRate < 0 )
00846         {
00847                 powerCommanded = (m_Coefficients2)(1)*pow( scaledWheelRate, 2 ) + (m_Coefficients2)(2)*scaledWheelRate + (m_Coefficients2)(3);
00848         }
00849         else if ( scaledWheelRate >= 0 && scaledWheelRate<= 1.2 )
00850         {
00851                 powerCommanded = (m_Coefficients3)(1)*pow( scaledWheelRate, 2 ) + (m_Coefficients3)(2)*scaledWheelRate + (m_Coefficients3)(3);
00852         }
00853         else if ( scaledWheelRate > 1.2 && scaledWheelRate <= 7.6 )
00854         {
00855                 powerCommanded = (m_Coefficients4)(1)*pow( scaledWheelRate, 3 ) +  (m_Coefficients4)(2)*pow( scaledWheelRate, 2 ) +  (m_Coefficients4)(3)*scaledWheelRate +  (m_Coefficients4)(4);
00856         }
00857         else
00858         {
00859                 // The Motor will maintain the previous voltage
00860                 cerr << "\nWARNING: OUTSIDE POWER COMMANDED to MOTOR BOUNDS. No Power setting sent to Wheel Motor.  Wheel: " << m_WheelName 
00861                 << "   Scaled Wheel Rate = " << scaledWheelRate << endl << endl;
00862                 return; 
00863         }
00864 
00865         TorqueCommand( powerCommanded );
00866         LAST_VOLT = volts;
00867 
00868         return;
00869 }
00870 
00871 void PhysicalMomentumWheel::StartPID( )
00872 {
00873         pthread_create( &m_PIDThreadID, NULL, RunPIDController, (void*) this);
00874 }
00875 
00876 void* RunPIDController(void* arg)
00877 {
00878         PhysicalMomentumWheel *wheel = (PhysicalMomentumWheel*) arg;
00879         double J = 0.04; //
00880         double c = 555.56;//unit conversion factor = 1 machine torque unit/0.0018 N-m
00881         double pi = 3.1415926535897;
00882         double timestep = 1000.0;
00883         double velocity;
00884         double desiredV;
00885         double error;
00886         double Kp;
00887         double Ki;
00888         double Kd;
00889         double torque;
00890         double TorqueChange;
00891         //static char *torqueCommand = new char[80];
00892         usleep(15000);
00893         while (1)
00894         {
00895                 pthread_testcancel();
00896 
00897                 cout << "PID THREAD RUNNING" << endl;
00898 
00899                 pthread_mutex_lock(&wheel->m_Mutex);
00900                 velocity = wheel->m_CurrentWheelSpeed/2.0/pi;
00901                 desiredV = wheel->m_DesiredWheelSpeed/2.0/pi;//desired velocity in RPS
00902                 pthread_mutex_unlock(&wheel->m_Mutex);
00903         
00904                 error = desiredV - velocity;//current error in RPS
00905         
00906                 cout << "current speed = " << velocity << endl;
00907                 cout << "desired speed = " << desiredV << endl;
00908                 cout << "error = " << error << endl;
00909 
00910                 // Define gains
00911                 Kp = 9.65*J/c;
00912         
00913                 Ki = 0.0000055;
00914                 if (fabs(error) >= 25 | fabs(desiredV) >= 25)
00915                 {
00916                         Ki = 0.0000013;
00917                 }
00918                 
00919                 Kd = 0.96*(fabs(error)*0.009029 + 1.92)*J/c; //linear regression equation
00920                 if (fabs(error) >= 25 | fabs(desiredV) >= 25)
00921                 { 
00922                         Kd = 2.14*J/c;
00923                 }
00924         
00925         
00926                 TorqueChange = c*(Kp*error + Kd*(error - wheel->LAST_ERR)/timestep + Ki*error*timestep);
00927         
00928                 cout << "Torque Change = " << TorqueChange << endl;     
00929 
00930                 torque = wheel->LAST_TOR + TorqueChange;
00931 
00932                 cout << "torqueA: " << torque << endl;
00933                 
00934                 //Limit Excessive Torques changes
00935                 if (abs((int) wheel->LAST_TOR - torque) > wheel->m_MaxTorqueStep  && torque != 0)
00936                 {
00937                         if ((int) wheel->LAST_TOR >= 0 && (int) wheel->LAST_TOR < torque){
00938                                 torque = (int) wheel->LAST_TOR + 300;}
00939                         else if ((int) wheel->LAST_TOR >= 0 && (int) wheel->LAST_TOR > torque){
00940                                 torque = (int) wheel->LAST_TOR - 300;}
00941                         else if ((int) wheel->LAST_TOR < 0 && (int) wheel->LAST_TOR < torque){
00942                                 torque = (int) wheel->LAST_TOR + 300;}
00943                         else if ((int) wheel->LAST_TOR < 0 && (int) wheel->LAST_TOR > torque){
00944                                 torque = (int) wheel->LAST_TOR - 300;}
00945                 }
00946                 
00947                 cout << "torque1: " << torque << endl;
00948 
00949                 cout << "max: " << wheel->m_MaxWheelTorque << endl;
00950 
00951                 // account for dead band
00952                 if (torque >= 0 && torque < 25.5 )
00953                 {
00954                         torque = torque + 25.5;
00955                 }
00956                 else if (torque < 0 && torque > -25.5 )
00957                 {
00958                         torque = torque - 25.5;
00959                 }
00960                 else
00961                 { }
00962 
00963                 // Cap maximum torque values
00964                 //if (abs(torque) > wheel->m_MaxWheelTorque)
00965                 if (abs(torque) > 800 )
00966                 {
00967                         torque = (int) wheel->LAST_TOR;
00968                 }
00969 
00970                 cout << "torque: " << torque << endl;
00971 
00972                 wheel->TorqueCommand( -int(torque) );   
00973                 /*
00974                 sprintf(torqueCommand, "T%d\n\n", (int)torque);
00975                 say(wheel->m_fd, torqueCommand);
00976                 */
00977 
00978                 pthread_testcancel();
00979 
00980                 usleep(850000);
00981                 /*      This loop allows for the motor to spin up with the current torque before another
00982                 *       torque is applied. The allowable magnitude of spin up error is variable.  When the
00983                 *       current wheel velocity is far away from the desired velocity, the error is large allowing
00984                 *       for a faster spin up.  When the current velocity is close to the desired, the maximum error
00985                 *       is small to all for more precise control. A break from the loop is provided for when
00986                 *       the velocity error is very small, to keep from looping for an excessive amount of time.*/
00987                 /*double spinuperror = wheel->LAST_VEL - velocity;
00988                 while (fabs(spinuperror) > (fabs(error)/15)) {
00989                         wheel->LAST_VEL = velocity;
00990                         usleep(20000);
00991                         pthread_mutex_lock(&wheel->m_Mutex);
00992                         velocity = wheel->m_CurrentWheelSpeed/2.0/pi;
00993                         pthread_mutex_unlock(&wheel->m_Mutex);
00994                         spinuperror = wheel->LAST_VEL - velocity;
00995                         error = desiredV - velocity;
00996                         if (fabs(error)<0.05){ break;}
00997                         pthread_testcancel();
00998                 }
00999                 */
01000                 wheel->LAST_VEL = velocity;
01001                 wheel->LAST_ERR = error;
01002                 wheel->LAST_TOR = torque;
01003                 pthread_testcancel();
01004         }
01005         return arg;
01006 }
01007 
01008 void PhysicalMomentumWheel::StopPID()
01009 {
01010         pthread_cancel(m_PIDThreadID);
01011         pthread_mutex_unlock(&m_Mutex);
01012 }
01013 
01014 void PhysicalMomentumWheel::CommandSystemTorque( double wheelTorque )
01015 {
01016         //Old-Skool command a Pork in Tower mode function.
01017         pthread_mutex_lock(&m_Mutex);
01018         //Torque input a double in n-m  
01019         wheelTorque = -wheelTorque/0.0018;
01020         wheelTorque = round(wheelTorque);
01021         int torque;
01022         torque = (int) wheelTorque;
01023         //Limit Excessive Torques changes
01024         if (abs((int)LAST_TOR - torque) > m_MaxTorqueStep  && torque != 0)
01025         {
01026                 if ((int) LAST_TOR >= 0 && (int) LAST_TOR < torque){
01027                         torque = (int) LAST_TOR + 600;}
01028                 else if ((int) LAST_TOR >= 0 && (int) LAST_TOR > torque){
01029                         torque = (int) LAST_TOR - 600;}
01030                 else if ((int) LAST_TOR < 0 && (int) LAST_TOR < torque){
01031                         torque = (int) LAST_TOR + 600;}
01032                 else if ((int) LAST_TOR < 0 && (int) LAST_TOR > torque){
01033                         torque = (int) LAST_TOR - 600;}
01034         }
01035 
01036         // Cap maximum torque values
01037         if (abs(torque) > m_MaxWheelTorque)
01038         {
01039                 torque = (int) LAST_TOR;
01040         }
01041 
01042         static char *torqueCommand = new char[80];
01043         sprintf(torqueCommand, "T%d\n\n", torque);
01044         say(m_fd, torqueCommand);
01045 
01046         m_CurrentWheelTorque = wheelTorque;
01047         
01048         //LAST_TOR = power ;
01049 
01050         pthread_mutex_unlock(&m_Mutex);
01051 }
01052 
01053 
01054 
01055 //////////////////////////////////////////////////////////
01056 // Mutators
01057 //////////////////////////////////////////////////////////
01058 
01059 void PhysicalMomentumWheel::SetWheelTorqueLimits(const double& minWheelTorque, const double& maxWheelTorque)
01060 {
01061     m_MaxWheelTorque = maxWheelTorque;
01062     m_MinWheelTorque = minWheelTorque;
01063 }
01064 
01065 
01066 void PhysicalMomentumWheel::SetMaxTorqueStep(double maxTorqueStep)
01067 {
01068     m_MaxTorqueStep = maxTorqueStep;
01069 }
01070 
01071 void PhysicalMomentumWheel::SetWheelAddress(int WheelAddress)
01072 {
01073         m_WheelAddress = 0x80 + WheelAddress;
01074 }
01075 
01076 void PhysicalMomentumWheel::SetDaisyChainNumber(int DaisyChainNumber)
01077 {
01078         m_DaisyChainNumber = DaisyChainNumber;
01079 
01080 }
01081 
01082 void PhysicalMomentumWheel::SetDaisyChainPort(string DaisyChainPort)
01083 {
01084         m_DaisyChainPort = DaisyChainPort;
01085 }
01086 
01087 void PhysicalMomentumWheel::SetBiasSpeed(double BiasSpeed)
01088 {
01089         m_BiasSpeed = BiasSpeed;
01090         if( m_BiasSpeed != 0 )
01091         {
01092                 m_BiasFlag = 1;
01093         }
01094 }
01095 
01096 void PhysicalMomentumWheel::SetAxialInertia(double _inertia)
01097 {
01098         m_AxialInertia = _inertia;
01099 }
01100 
01101 void PhysicalMomentumWheel::SetWheelName( string _wheelName )
01102 {
01103         m_WheelName = _wheelName;
01104 }
01105 
01106 void PhysicalMomentumWheel::SetWheelSpeedCoefficients( Vector _Coefficients1, Vector _Coefficients2, Vector _Coefficients3, Vector _Coefficients4 )
01107 {
01108         (m_Coefficients1)(_(1,4)) = _Coefficients1;
01109         (m_Coefficients2)(_(1,3)) = _Coefficients2;
01110         (m_Coefficients3)(_(1,3)) = _Coefficients3;
01111         (m_Coefficients4)(_(1,4)) = _Coefficients4;
01112 }
01113 //////////////////////////////////////////////////////
01114 // Inspectors
01115 //////////////////////////////////////////////////////
01116 
01117 void PhysicalMomentumWheel::GetWheelSpeed(double& Speed, double& measTime)
01118 {
01119         pthread_mutex_lock(&m_Mutex);
01120         Speed = m_CurrentWheelSpeed;
01121         measTime = m_VelocityTime;
01122         pthread_mutex_unlock(&m_Mutex);
01123 }
01124     
01125 
01126 double PhysicalMomentumWheel::QueryWheelTorque()
01127 {
01128         pthread_mutex_lock(&m_Mutex);
01129         //Clear Buffer
01130         static char *clear = new char[80];
01131         hear(m_fd, clear, 79, 0, 3333, '\r');
01132         
01133         //Send command  
01134         static char *RTCommand = new char[80];
01135         sprintf(RTCommand, "RT\n\n");
01136         say(m_fd, RTCommand);
01137 
01138         static char *torqueString = new char[80];
01139         hear(m_fd, torqueString, 20, 0, 10000, '\r');
01140         
01141         double Wtorque = atoi(torqueString+3) * 0.0018;//0.018 N-m per machine torque unit
01142         
01143         m_CurrentWheelTorque = Wtorque;
01144         
01145         delete clear;
01146         delete RTCommand;
01147         
01148         pthread_mutex_unlock(&m_Mutex);
01149         return Wtorque;
01150 }
01151 
01152 void PhysicalMomentumWheel::GetAxialInertia( double& _inertia )
01153 {
01154         _inertia = m_AxialInertia;
01155 }
01156 
01157 double PhysicalMomentumWheel::GetAxialInertia( )
01158 {
01159         return( m_AxialInertia );
01160 }
01161 
01162 string PhysicalMomentumWheel::GetWheelName( )
01163 {
01164         return( m_WheelName );
01165 }
01166 
01167 void PhysicalMomentumWheel::GetWheelTorqueLimits(double& minWheelTorque, double& maxWheelTorque)
01168 {
01169     maxWheelTorque = m_MaxWheelTorque;
01170     minWheelTorque = m_MinWheelTorque;
01171     return;
01172 }
01173 
01174 
01175 void PhysicalMomentumWheel::GetMaxTorqueStep(double& maxTorqueStep)
01176 {
01177     maxTorqueStep = m_MaxTorqueStep;
01178     return;
01179 }
01180 
01181 int PhysicalMomentumWheel::GetWheelFD()
01182 {
01183         return m_fd;
01184 }
01185 
01186 double PhysicalMomentumWheel::GetAmps()
01187 {
01188         char *ampString = new char[80];
01189         double mamps;
01190         double amps;
01191         //clear serial port buffer
01192         //char* clear = new char[80];
01193         
01194         char *VarCommand = new char[80];
01195         sprintf(VarCommand, "a=UIA\rRa\n");
01196         
01197         pthread_mutex_lock(&m_Mutex);
01198 
01199                 //while( !hear(m_fd, clear, 79, 0, 3333, 'c'));
01200 
01201                 say(m_fd, VarCommand);
01202         
01203                 //usleep(15000);
01204                 //hear(m_fd, clear, 25, 0, 10000, '\n');
01205 
01206                 //hear(m_fd, ampString, 15, 0, 10000, '\r');
01207         
01208                 hear(m_fd, ampString, 15, 0, 60000, '\r');
01209         
01210         pthread_mutex_unlock(&m_Mutex);
01211 
01212         mamps = atoi(ampString);
01213         amps = mamps/100;
01214         
01215         return amps;
01216 }
01217 
01218 double PhysicalMomentumWheel::GetVolts()
01219 {
01220         char *voltString = new char[80];
01221         double mvolts;
01222         double volts;
01223         //clear serial port buffer
01224         char* clear = new char[80];
01225         
01226         char *VarCommand = new char[80];
01227         sprintf(VarCommand, "b=UJA\rRb\n");
01228         
01229         pthread_mutex_lock(&m_Mutex);
01230 
01231                 while( !hear(m_fd, clear, 79, 0, 3333, 'c'));
01232 
01233                 say(m_fd, VarCommand);
01234 
01235                 //usleep(15000);
01236                 //hear(m_fd, clear, 25, 0, 10000, '\n');
01237         
01238                 //hear(m_fd, voltString, 15, 0, 10000, '\r');
01239                 hear(m_fd, voltString, 15, 0, 60000, '\r');
01240         pthread_mutex_unlock(&m_Mutex);
01241         
01242         mvolts = atoi(voltString);
01243         volts = mvolts/10;
01244         
01245         return volts;
01246 }
01247 // Do not change the comments below - they will be added automatically by CVS
01248 /*****************************************************************************
01249 *       $Log: PhysicalMomentumWheel.cpp,v $
01250 *       Revision 1.44  2007/08/31 15:48:03  jayhawk_hokie
01251 *       Updated.
01252 *       
01253 *       Revision 1.43  2007/07/24 09:39:39  jayhawk_hokie
01254 *       Removed matrix and vector pointers.
01255 *       
01256 *       Revision 1.42  2007/05/30 23:48:43  jayhawk_hokie
01257 *       Modified thread termination.
01258 *       
01259 *       Revision 1.41  2007/05/23 22:09:16  jayhawk_hokie
01260 *       Removed reducing wheel speed comments.
01261 *       
01262 *       Revision 1.40  2007/05/22 18:21:50  jayhawk_hokie
01263 *       *** empty log message ***
01264 *       
01265 *       Revision 1.39  2007/04/09 14:01:31  jayhawk_hokie
01266 *       Added capability in Torque Controller to reduce wheel speed.
01267 *       
01268 *       Revision 1.38  2007/03/27 19:39:02  jayhawk_hokie
01269 *       Removed Unused Variable.
01270 *       
01271 *       Revision 1.37  2007/03/27 19:07:16  jayhawk_hokie
01272 *       Updated Momentum Wheels.
01273 *       
01274 *       Revision 1.36  2007/02/06 20:56:23  jayhawk_hokie
01275 *       Added SetAxialInertia function.
01276 *       
01277 *       Revision 1.35  2005/08/29 20:15:32  tjdpw
01278 *       Removed unnecessary thread cancellations that caused seg fault.
01279 *       
01280 *       Revision 1.34  2005/02/25 18:40:52  cakinli
01281 *       Created Makefiles and organized include directives to reduce the number of
01282 *       include paths.  Reorganized libraries so that there is now one per source
01283 *       directory.  Each directory is self-contained in terms of its Makefile.
01284 *       The local Makefile in each directory includes src/config.mk, which has all
01285 *       the definitions and general and pattern rules.  So at most, to see what
01286 *       goes into building a target, a person needs to examine the Makefile in
01287 *       that directory, and ../config.mk.
01288 *       
01289 *       Revision 1.33  2004/05/11 20:18:08  bstreetman
01290 *       Vast improvements to torque controller
01291 *       
01292 *       Revision 1.32  2004/04/19 15:00:43  bstreetman
01293 *       Fixed a config and a shutdown bug
01294 *       
01295 *       Revision 1.31  2004/03/18 18:08:17  bstreetman
01296 *       Further Fixes on the torque controller
01297 *       
01298 *       Revision 1.25  2004/03/15 21:58:31  bstreetman
01299 *       Fixed a multible multi-thread issue.
01300 *       
01301 *       Revision 1.24  2004/03/04 23:13:09  bstreetman
01302 *       Big changes! new functions and functionality.  FUnctions: GetVolts() -- get motor voltage.  GetAmps() -- ge current used by motors.  GetWheelFD() -- get the wheel comm file descriptor.  SetBiasSpeed() -- Set the bias speed used in momentum wheel mode.  SetSystemTorque() -- old style torque function, used mainly by me.  friend RUnTorqueCOntroller() -- new torque controller, runs in a separate thread.  StartTorqueController() -- spawns torque thread, called internally.  Other Changes:  config parameters -- added BiasSpeed confige parameter, sets bias speed and commands the wheel to go there.  SetWheelSpeed() -- no more PID controller, uses a function created by the data i took.  SetWHeelTorque() -- happens in a better way now based on tons of data and hdot = g.
01303 ******************************************************************************/

Generated on Wed Sep 5 12:54:24 2007 for DSACSS Operational Code by  doxygen 1.3.9.1