BeobotControl.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "Beobot/BeobotControl.H"
00038 #include "Component/OptionManager.H"
00039 #include "Util/Types.H"
00040 #include "Util/log.H"
00041 #include <math.h>
00042
00043 #define MAX_SERVO_MOVE .10
00044
00045
00046 void *speedRampFunc( void *ptr )
00047 {
00048
00049 const int signalsPerSecond = 50;
00050 const uint64 delayPerSignal = 1000000 / signalsPerSecond;
00051
00052 float startSpeed;
00053 float desiredSpeed;
00054 int desiredTime;
00055 int currentTime;
00056 SpeedRampType type;
00057
00058 bool threadOK;
00059 Timer tmr( 1000000 );
00060
00061
00062 BeobotControl *bc = reinterpret_cast<BeobotControl *>(ptr);
00063
00064
00065 do
00066 {
00067
00068 tmr.reset();
00069
00070
00071 pthread_mutex_lock( &(bc->speedRampMutex) );
00072
00073 startSpeed = bc->startSpeed;
00074 desiredSpeed = bc->desiredSpeed;
00075 desiredTime = bc->desiredTime;
00076 currentTime = bc->speedRampTimer.get();
00077 type = bc->speedRampType;
00078 threadOK = bc->speedRampThreadCreated;
00079
00080
00081 pthread_mutex_unlock( &(bc->speedRampMutex) );
00082
00083 if( threadOK )
00084 {
00085
00086 if( currentTime >= desiredTime )
00087 {
00088 LDEBUG( "Time's up! Will exit speed ramping thread..." );
00089 break;
00090 }
00091
00092
00093 else
00094 {
00095 switch( type )
00096 {
00097 case SPEED_RAMP_LINEAR:
00098 bc->setSpeed( startSpeed + ( desiredSpeed - startSpeed ) /
00099 desiredTime * currentTime );
00100 break;
00101 case SPEED_RAMP_SIGMOID:
00102 bc->setSpeed( startSpeed + ( desiredSpeed - startSpeed ) *
00103 ( 1.0f / ( 1.0f +
00104 exp( -10.0f / desiredTime *
00105 currentTime + 5.0f ) ) ) );
00106 break;
00107 default:
00108
00109 LERROR( "Invalid speed ramping type: %d", type );
00110 break;
00111 }
00112 }
00113 }
00114
00115
00116 while( tmr.get() < delayPerSignal )
00117 {
00118
00119 }
00120 }
00121 while( threadOK );
00122
00123 LDEBUG( "Speed ramping thread finished" );
00124 pthread_mutex_lock( &(bc->speedRampMutex ) );
00125 bc->speedRampThreadCreated = false;
00126 pthread_mutex_unlock( &(bc->speedRampMutex ) );
00127
00128 return 0;
00129 }
00130
00131
00132 BeobotControl::BeobotControl(nub::soft_ref<BeoChip> beoChip,
00133 OptionManager& mgr, const std::string& descrName,
00134 const std::string& tagName) :
00135 ModelComponent(mgr, descrName, tagName),
00136 itsBeoChip(beoChip),
00137 speedRampTimer( 1000 )
00138 {
00139
00140
00141
00142
00143 itsBeoChip->setServoRaw(itsBeobotConfig.speedServoNum,
00144 itsBeobotConfig.speedNeutralVal);
00145 itsBeoChip->setServoRaw(itsBeobotConfig.steerServoNum,
00146 itsBeobotConfig.steerNeutralVal);
00147 itsBeoChip->setServoRaw(itsBeobotConfig.gearServoNum,
00148 itsBeobotConfig.gearMinVal);
00149
00150
00151 speedRampThreadCreated = false;
00152 }
00153
00154
00155 BeobotControl::~BeobotControl(){ }
00156
00157
00158 float BeobotControl::getSpeed() const
00159 { return itsBeoChip->getServo(itsBeobotConfig.speedServoNum); }
00160
00161
00162 float BeobotControl::getSteer() const
00163 { return itsBeoChip->getServo(itsBeobotConfig.steerServoNum); }
00164
00165
00166 float BeobotControl::getGear() const
00167 { return itsBeoChip->getServo(itsBeobotConfig.gearServoNum ); }
00168
00169
00170 bool BeobotControl::setSpeed(const float newspeed)
00171 {
00172
00173 float procspeed = newspeed;
00174 if(newspeed > 1.0f) procspeed = 1.0f;
00175 else if(newspeed < -1.0f) procspeed = -1.0f;
00176
00177 pthread_mutex_lock( &setSpeedMutex );
00178
00179
00180 float currspeed = getSpeed();
00181 if(procspeed > currspeed + MAX_SERVO_MOVE)
00182 procspeed = currspeed + MAX_SERVO_MOVE;
00183 else if(procspeed < currspeed - MAX_SERVO_MOVE)
00184 procspeed = currspeed - MAX_SERVO_MOVE;
00185
00186 bool setOK =
00187 itsBeoChip->setServo(itsBeobotConfig.speedServoNum, procspeed);
00188 pthread_mutex_unlock( &setSpeedMutex );
00189 return setOK;
00190 }
00191
00192
00193 bool BeobotControl::setSteer(const float newsteer)
00194 {
00195
00196 float procsteer = newsteer;
00197 if(newsteer > 1.0f) procsteer = 1.0f;
00198 else if(newsteer < -1.0f) procsteer = -1.0f;
00199
00200
00201 float currsteer = getSteer();
00202 if(procsteer > currsteer + MAX_SERVO_MOVE)
00203 procsteer = currsteer + MAX_SERVO_MOVE;
00204 else if(procsteer < currsteer - MAX_SERVO_MOVE)
00205 procsteer = currsteer - MAX_SERVO_MOVE;
00206
00207 return itsBeoChip->setServo(itsBeobotConfig.steerServoNum, procsteer);
00208 }
00209
00210
00211 bool BeobotControl::setGear(const float newgear)
00212 {
00213
00214 float procgear = newgear;
00215 if(newgear > 1.0f) procgear = 1.0f;
00216 else if(newgear < -1.0f) procgear = -1.0f;
00217
00218
00219 float currgear = getGear();
00220 if(procgear > currgear + MAX_SERVO_MOVE)
00221 procgear = currgear + MAX_SERVO_MOVE;
00222 else if(procgear < currgear - MAX_SERVO_MOVE)
00223 procgear = currgear - MAX_SERVO_MOVE;
00224
00225 return itsBeoChip->setServo(itsBeobotConfig.gearServoNum, procgear);
00226 }
00227
00228
00229 void BeobotControl::stop1()
00230 {
00231
00232 pthread_cancel( speedRampThread );
00233
00234
00235 setSpeed(0.0F);
00236 setSteer(0.0F);
00237 setGear (0.0F);
00238 }
00239
00240
00241 bool BeobotControl::toSpeedLinear( const float newspeed, const int t )
00242 {
00243 float current = getSpeed();
00244
00245
00246 int calls = (int)( t / 1000.0 * 30 + 0.5 );
00247 if( calls <= 1 )
00248 {
00249 return setSpeed( newspeed );
00250 }
00251
00252 else
00253 {
00254 bool speedChangeOk = true;
00255 float delta = ( newspeed - current ) / calls;
00256 for( int i = 0; i < calls; i++ )
00257 {
00258 speedChangeOk = speedChangeOk && setSpeed( current + delta * i );
00259 Timer tim( 1000000 );
00260 while( tim.get() < 33333 )
00261 {
00262
00263 }
00264 }
00265 return speedChangeOk;
00266 }
00267 }
00268
00269
00270 bool BeobotControl::toSpeedSigmoid( const float newspeed, const int t )
00271 {
00272 float current = getSpeed();
00273
00274
00275 int calls = (int)( t / 1000.0 * 30 + 0.5 );
00276 if( calls <= 1 )
00277 {
00278 return setSpeed( newspeed );
00279 }
00280
00281 else
00282 {
00283 bool speedChangeOk = true;
00284 for( int i = 0; i < calls; i++ )
00285 {
00286 speedChangeOk = speedChangeOk &&
00287 setSpeed( current + ( newspeed - current ) /
00288 ( 1 + exp( -11.0825 / calls * ( i - calls/2 ) ) ) );
00289 Timer tim( 1000000 );
00290 while( tim.get() < 33333 )
00291 {
00292
00293 }
00294 }
00295 return speedChangeOk;
00296 }
00297
00298 return true;
00299 }
00300
00301
00302 void BeobotControl::rampSpeed( const float newspeed, const int t,
00303 SpeedRampType behavior )
00304 {
00305
00306 pthread_mutex_lock( &speedRampMutex );
00307
00308 startSpeed = getSpeed();
00309 desiredSpeed = newspeed;
00310 desiredTime = t;
00311 speedRampType = behavior;
00312 speedRampTimer.reset();
00313
00314
00315 pthread_mutex_unlock( &speedRampMutex );
00316
00317
00318 if( !speedRampThreadCreated )
00319 {
00320 speedRampThreadCreated = true;
00321 pthread_create( &speedRampThread, NULL, speedRampFunc,
00322 reinterpret_cast<void *>(this) );
00323 }
00324 }
00325
00326
00327 void BeobotControl::abortRamp( void )
00328 {
00329 if( speedRampThreadCreated )
00330 {
00331 speedRampThreadCreated = false;
00332 pthread_cancel( speedRampThread );
00333 }
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347