00001
00012 #include <pthread.h>
00013 #include <purepursuit_planner/Component.h>
00014
00015
00020 void *AuxControlThread(void *threadParam){
00021 Component *ComponentThread = (Component *)threadParam;
00022 ComponentThread->ControlThread();
00023 pthread_detach(pthread_self());
00024 return NULL;
00025 }
00026
00031 Component::Component(double desired_hz){
00032
00033 bInitialized = bRunning = false;
00034 threadData.dRealHz = 0.0;
00035 if(desired_hz <= 0.0)
00036 desired_hz = DEFAULT_THREAD_DESIRED_HZ;
00037 threadData.dDesiredHz = desired_hz;
00038 iState = SHUTDOWN_STATE;
00039
00040 sComponentName.assign("Component");
00041
00042
00043 pthread_mutex_init(&mutexThread, NULL);
00044
00045 threadData.pthreadPar.prio = 25;
00046 threadData.pthreadPar.clock= CLOCK_REALTIME;
00047 }
00048
00052 Component::~Component(){
00053
00054 pthread_mutex_destroy(&mutexThread);
00055 }
00056
00063 ReturnValue Component::Setup(){
00064
00065 if(bInitialized){
00066 ROS_INFO("%s::Setup: Already initialized",sComponentName.c_str());
00067
00068 return INITIALIZED;
00069 }
00070
00071
00073
00075
00077
00078 if(Allocate() != OK){
00079 ROS_ERROR("%s::Setup: Error in Allocate",sComponentName.c_str());
00080 return ERROR;
00081 }
00082
00083 if(Open() != OK){
00084 ROS_ERROR("%s::Setup: Error in Open",sComponentName.c_str());
00085
00086 return ERROR;
00087 }
00088
00089
00090 if(Configure() != OK){
00091 ROS_ERROR("%s::Setup: Error in Configure",sComponentName.c_str());
00092 return ERROR;
00093 }
00094
00095 bInitialized = true;
00096
00097 return OK;
00098 }
00099
00107 ReturnValue Component::ShutDown(){
00108
00109 if(bRunning){
00110 ROS_INFO("%s::ShutDown: Impossible while thread running, first must be stopped",sComponentName.c_str());
00111 return THREAD_RUNNING;
00112 }
00113 if(!bInitialized){
00114 ROS_INFO("%s::ShutDown: Impossible because of it's not initialized", sComponentName.c_str());
00115 return NOT_INITIALIZED;
00116 }
00117
00118
00120
00122
00123 if(Close() != OK){
00124 ROS_ERROR("%s::ShutDown: Error Closing", sComponentName.c_str());
00125 return ERROR;
00126 }
00127 if(Free() != OK){
00128 ROS_ERROR("%s::ShutDown: Error in Free", sComponentName.c_str());
00129 return ERROR;
00130 }
00131
00132 bInitialized = false;
00133
00134 return OK;
00135 }
00136
00142 ReturnValue Component::Configure(){
00143
00144 return OK;
00145 }
00146
00151 ReturnValue Component::Allocate(){
00152
00153 return OK;
00154 }
00155
00160 ReturnValue Component::Free(){
00161
00162 return OK;
00163 }
00164
00170 ReturnValue Component::Open(){
00171
00172 return OK;
00173 }
00174
00180 ReturnValue Component::Close(){
00181
00182 return OK;
00183 }
00184
00191 ReturnValue Component::Start(){
00192
00193 pthread_attr_t attr;
00194
00195
00196 if(!bInitialized){
00197 ROS_INFO("%s::Start: the component is not initialized", sComponentName.c_str());
00198 return NOT_INITIALIZED;
00199 }
00200
00202
00204
00205 if(!bRunning) {
00206 ROS_INFO("%s::Start: launching the thread", sComponentName.c_str());
00207
00208
00209 pthread_attr_init(&attr);
00210 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00211 bRunning = true;
00212
00213 if(pthread_create(&threadData.pthreadId, &attr, AuxControlThread, this) != 0) {
00214 ROS_ERROR("%s::Start: Could not create ControlThread", sComponentName.c_str());
00215
00216 pthread_attr_destroy(&attr);
00217 bRunning = false;
00218 return ERROR;
00219 }
00220
00221 pthread_attr_destroy(&attr);
00222 return OK;
00223
00224 }else {
00225 ROS_INFO("%s::Start: the component's thread is already running", sComponentName.c_str());
00226 return THREAD_RUNNING;
00227 }
00228
00229 }
00230
00237 ReturnValue Component::Stop(){
00238
00239 if(!bRunning){
00240 ROS_INFO("%s::Stop: Thread not running", sComponentName.c_str());
00241
00242 return THREAD_NOT_RUNNING;
00243 }
00244
00246
00248
00249 ROS_INFO("%s::Stop: Stopping the thread", sComponentName.c_str());
00250
00251 bRunning = false;
00252
00253 usleep(100000);
00254
00255 return OK;
00256 }
00257
00261 void Component::ControlThread(){
00262 struct sched_param schedp;
00263 int policy = threadData.pthreadPar.prio? SCHED_FIFO : SCHED_OTHER;
00264 struct timespec now, next, interval;
00265 struct timespec last_time;
00266 long diff;
00267 unsigned long sampling_period_us;
00268
00269
00270 memset(&schedp, 0, sizeof(schedp));
00271 schedp.sched_priority = threadData.pthreadPar.prio;
00272 sched_setscheduler(0, policy, &schedp);
00273 clock_gettime(threadData.pthreadPar.clock, &now);
00274 last_time = next = now;
00275 next.tv_sec++;
00276 sampling_period_us = (long unsigned int) (1.0 / threadData.dDesiredHz * 1000000.0);
00277 interval.tv_sec = sampling_period_us / USEC_PER_SEC;
00278 interval.tv_nsec = (sampling_period_us % USEC_PER_SEC)*1000;
00279
00280
00281
00282
00283 SwitchToState(INIT_STATE);
00284
00285 while(bRunning) {
00286 clock_nanosleep(threadData.pthreadPar.clock, TIMER_ABSTIME, &next, NULL);
00287 clock_gettime(threadData.pthreadPar.clock, &now);
00288 next.tv_sec += interval.tv_sec;
00289 next.tv_nsec += interval.tv_nsec;
00290 tsnorm(&next);
00291
00292 diff = calcdiff(now, last_time);
00293 last_time = now;
00294
00295 threadData.dRealHz = 1.0/(diff / 1000000.0);
00296
00297 if(threadData.dRealHz < (1.0/5.0)*threadData.dDesiredHz){
00298 ROS_ERROR("%s:ControlThread: Delay on control loop. Desired Hz is %lf, but real is %lf", sComponentName.c_str(), threadData.dDesiredHz, threadData.dRealHz);
00299
00300 }
00301
00302 switch (iState){
00303 case INIT_STATE:
00304 InitState();
00305 break;
00306 case STANDBY_STATE:
00307 StandbyState();
00308 break;
00309 case READY_STATE:
00310 ReadyState();
00311 break;
00312 case EMERGENCY_STATE:
00313 EmergencyState();
00314 break;
00315 case FAILURE_STATE:
00316 FailureState();
00317 break;
00318 default:
00319 break;
00320 }
00321 AllState();
00322 }
00323 SwitchToState(SHUTDOWN_STATE);
00324
00325 ROS_INFO("%s:ControlThread: Exiting main Thread", sComponentName.c_str());
00326
00327 usleep(100000);
00328
00329 }
00330
00334 void Component::InitState(){
00335
00336 }
00337
00341 void Component::StandbyState(){
00342
00343 }
00344
00348 void Component::ReadyState(){
00349
00350 }
00351
00355 void Component::EmergencyState(){
00356
00357 }
00358
00362 void Component::FailureState(){
00363
00364 }
00365
00369 void Component::AllState(){
00370
00371 }
00372
00377 double Component::GetUpdateRate(){
00378 return threadData.dRealHz;
00379 }
00380
00384 States Component::GetState(){
00385 return iState;
00386 }
00387
00391 char *Component::GetStateString(){
00392 switch(iState){
00393 case INIT_STATE:
00394 return (char *)"INIT";
00395 break;
00396 case STANDBY_STATE:
00397 return (char *)"STANDBY";
00398 break;
00399 case READY_STATE:
00400 return (char *)"READY";
00401 break;
00402 case EMERGENCY_STATE:
00403 return (char *)"EMERGENCY";
00404 break;
00405 case FAILURE_STATE:
00406 return (char *)"FAILURE";
00407 break;
00408 case SHUTDOWN_STATE:
00409 return (char *)"SHUTDOWN";
00410 break;
00411 default:
00412 return (char *)"UNKNOWN";
00413 break;
00414 }
00415 }
00416
00420 char *Component::GetStateString(States state){
00421 switch(state){
00422 case INIT_STATE:
00423 return (char *)"INIT";
00424 break;
00425 case STANDBY_STATE:
00426 return (char *)"STANDBY";
00427 break;
00428 case READY_STATE:
00429 return (char *)"READY";
00430 break;
00431 case EMERGENCY_STATE:
00432 return (char *)"EMERGENCY";
00433 break;
00434 case FAILURE_STATE:
00435 return (char *)"FAILURE";
00436 break;
00437 case SHUTDOWN_STATE:
00438 return (char *)"SHUTDOWN";
00439 break;
00440 default:
00441 return (char *)"UNKNOWN";
00442 break;
00443 }
00444 }
00445
00446
00451 void Component::SwitchToState(States new_state){
00452
00453 if(new_state == iState)
00454 return;
00455
00456
00457 ROS_INFO("%s::SwitchToState: %s -> %s", sComponentName.c_str(), GetStateString(iState), GetStateString(new_state));
00458 iState = new_state;
00459
00460 }
00461
00467 ReturnValue Component::GetThreadData(thread_data *data){
00468 pthread_t auxId = pthread_self();
00469 ReturnValue ret = ERROR;
00470
00471 if(auxId == threadData.pthreadId){
00472 *data = threadData;
00473 ROS_INFO("Component::GetThreadData: Main thread");
00474 return OK;
00475 }
00476
00477 pthread_mutex_lock(&mutexThread);
00478 for(unsigned int i = 0; i < vThreadData.size(); i++){
00479
00480 if(auxId == vThreadData[i].pthreadId){
00481 *data = vThreadData[i];
00482 ret = OK;
00483 break;
00484 }
00485 }
00486 pthread_mutex_unlock(&mutexThread);
00487
00488 return ret;
00489 }
00490
00500 ReturnValue Component::CreateTask(int prio, double frec, void *(*start_routine)(void*)){
00501 pthread_attr_t attr;
00502 thread_data new_thread;
00503 if(frec <= 0.0)
00504 frec = DEFAULT_THREAD_DESIRED_HZ;
00505 if(prio < 0)
00506 prio = DEFAULT_THREAD_PRIORITY;
00507
00508
00509 if(!bRunning){
00510 ROS_INFO("%s::CreateTask: the component is not running", sComponentName.c_str());
00511 return THREAD_NOT_RUNNING;
00512 }
00513
00514 pthread_attr_init(&attr);
00515 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00516
00517 pthread_mutex_lock(&mutexThread);
00518
00519
00520 if(pthread_create(&new_thread.pthreadId, &attr, start_routine, this) != 0) {
00521 ROS_ERROR("%s::CreateTask: Could not create new thread", sComponentName.c_str());
00522 pthread_attr_destroy(&attr);
00523 pthread_mutex_unlock(&mutexThread);
00524 return ERROR;
00525 }
00526 pthread_attr_destroy(&attr);
00527 new_thread.dDesiredHz = frec;
00528 new_thread.dRealHz = 0.0;
00529 new_thread.pthreadPar.prio = prio;
00530 new_thread.pthreadPar.clock = CLOCK_REALTIME;
00531
00532 vThreadData.push_back(new_thread);
00533
00534 pthread_mutex_unlock(&mutexThread);
00535
00536 return OK;
00537 }