Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include <tk_behavior/ActiveBehaviorContainer.hpp>
00009 #include <tk_behavior/BehaviorContainer.hpp>
00010 
00011 #include <tk_behavior/BehaviorController.hpp>
00012 
00013 namespace TELEKYB_NAMESPACE
00014 {
00015 
00016 ActiveBehaviorContainer::ActiveBehaviorContainer(Behavior* initialActiveBehavior)
00017         : activeBehaviorPtr( initialActiveBehavior ),
00018           options( BehaviorControllerOptions::Instance() ),
00019           seController( StateEstimatorController::Instance() ),
00020           behaviorController( BehaviorController::Instance() )
00021 {
00022 
00023 
00024         
00025         if (! seController.waitForFirstState( Time(options.tInitialStateTimeout->getValue()) ) ) {
00026                 
00027                 ROS_ERROR("BehaviorController: Did not receive initial TKState within Timeout! Using uninitialized! This is dangerous!");
00028         }
00029 
00030         
00031         activeBehaviorPtr->willBecomeActive( seController.getLastState(), *activeBehaviorPtr);
00032 
00033         
00034         activeBehaviorPtr->didBecomeActive( seController.getLastState(), *activeBehaviorPtr);
00035 
00036         
00037         transitionState = TransitionState::Active;
00038 
00039 }
00040 
00041 ActiveBehaviorContainer::~ActiveBehaviorContainer() {
00042         
00043 }
00044 
00045 
00046 void ActiveBehaviorContainer::trajectoryStep(const TKState& currentState, TKTrajectory& generatedTrajInput)
00047 {
00048         
00049         boost::mutex::scoped_lock lock(behaviorChangeRequestMutex);
00050 
00051         
00052         if (behaviorChangeMutex.try_lock()) {
00053 
00054                 
00055                 if (activeBehaviorPtr->isValid(currentState)) {
00056                         
00057                         activeBehaviorPtr->trajectoryStepActive(currentState, generatedTrajInput);
00058 
00059                         
00060                         behaviorChangeMutex.unlock();
00061                 } else {
00062                         
00063                         activeBehaviorPtr->trajectoryStepTermination(currentState, generatedTrajInput);
00064                         transitionState = TransitionState::Termination;
00065 
00066                         
00067                         Behavior* next = NULL; 
00068                         if (activeBehaviorPtr->hasNextBehavior()) {
00069                                 next = activeBehaviorPtr->getNextBehavior();
00070                         }
00071 
00072                         
00073                         if (!next || !checkNewBehavior(next)) {
00074                                 if (activeBehaviorPtr->getType() == BehaviorType::Ground) {
00075                                         next =  behaviorController.getSystemBehaviorContainer().getGround();
00076                                 } else {
00077                                         
00078                                         next = behaviorController.getSystemBehaviorContainer().getNormalBrake();
00079                                 }
00080                         }
00081 
00082 
00083                         
00084                         behaviorChangeThread = boost::thread(&ActiveBehaviorContainer::switchToBehaviorThread, this, next);
00085 
00086                         
00087                 }
00088 
00089         } else {
00090 
00091                 
00092                 
00093                 
00094 
00095                 switch (transitionState.index()) {
00096                 case TransitionState::Active:
00097                         if (activeBehaviorPtr->isValid(currentState)) {
00098                                 activeBehaviorPtr->trajectoryStepActive(currentState, generatedTrajInput);
00099                         } else {
00100                                 
00101                                 
00102                                 activeBehaviorPtr->trajectoryStepTermination(currentState, generatedTrajInput);
00103                         }
00104                         break;
00105                 case TransitionState::Termination:
00106                         activeBehaviorPtr->trajectoryStepTermination(currentState, generatedTrajInput);
00107                         break;
00108                 case TransitionState::Creation:
00109                         activeBehaviorPtr->trajectoryStepCreation(currentState, generatedTrajInput);
00110                         break;
00111                 default:
00112                         
00113                         break;
00114                 }
00115         }
00116 }
00117 
00118 bool ActiveBehaviorContainer::checkNewBehavior(Behavior* newBehavior) const
00119 {
00120         
00121         if (activeBehaviorPtr == newBehavior) {
00122                 ROS_ERROR_STREAM("Prevented Behavior Switch of " << activeBehaviorPtr->getName() << ", because the Behavior is already active!");
00123                 return false;
00124         }
00125 
00126         
00127         if (!BehaviorContainer::behaviorInstanceExists(newBehavior)) {
00128                 ROS_ERROR_STREAM("Cannot switch Behavior to ID " << (uint64_t)newBehavior << ", because it does not exist.");
00129                 return false;
00130         }
00131 
00132         
00133         if (!activeBehaviorPtr->canTransitionTo(*newBehavior)) {
00134                 ROS_ERROR_STREAM("Transition from "
00135                                 << activeBehaviorPtr->getName() << " (" <<  activeBehaviorPtr->getType().str() <<")"
00136                                 << " to "
00137                                 << newBehavior->getName() << " (" <<  newBehavior->getType().str() <<")"
00138                                 << " is an unallowed transition.");
00139                 return false;
00140         }
00141 
00142         
00143         if (!newBehavior->isParameterInitialized() ) {
00144                 ROS_ERROR_STREAM("Cannot switch to Behavior " << newBehavior->getName() <<
00145                                 " ID: "<< (uint64_t)newBehavior << ", because it is not Parameter Initalized!");
00146                 return false;
00147         }
00148 
00149         return true;
00150 }
00151 
00152 
00153 bool ActiveBehaviorContainer::switchToBehavior(Behavior* newBehavior)
00154 {
00155         
00156         boost::mutex::scoped_lock lock(behaviorChangeRequestMutex);
00157 
00158         
00159         if (!behaviorChangeMutex.try_lock()) {
00160                 ROS_ERROR_STREAM("Prevented Behavior Switch of " << activeBehaviorPtr->getName() << ", because a Switch is currently in progess!");
00161                 return false;
00162         }
00163 
00164         if (!checkNewBehavior(newBehavior)) {
00165                 
00166                 behaviorChangeMutex.unlock();
00167                 return false;
00168         }
00169 
00170         transitionState = TransitionState::Termination;
00171 
00172         
00173         behaviorChangeThread = boost::thread(&ActiveBehaviorContainer::switchToBehaviorThread, this, newBehavior);
00174 
00175         return true;
00176 }
00177 
00178 void ActiveBehaviorContainer::switchToBehaviorThread(Behavior* newBehavior)
00179 {
00180         
00181         if (!newBehavior->willBecomeActive( seController.getLastState(), *activeBehaviorPtr ) ) {
00182                 ROS_ERROR_STREAM("Cannot switch to Behavior " << newBehavior->getName() <<
00183                                 " ID: "<< newBehavior->getIDString() << ", because it denied the switch.");
00184 
00185 
00186                 
00187                 if (activeBehaviorPtr->getType() == BehaviorType::Ground) {
00188                         newBehavior =  behaviorController.getSystemBehaviorContainer().getGround();
00189                 } else {
00190                         
00191                         newBehavior = behaviorController.getSystemBehaviorContainer().getNormalBrake();
00192                 }
00193 
00194                 
00195                 if (newBehavior == activeBehaviorPtr) {
00196                         behaviorChangeMutex.unlock();
00197                         return;
00198                 }
00199 
00200 
00201                 
00202                 if (!newBehavior->willBecomeActive( seController.getLastState(), *activeBehaviorPtr )) {
00203                         ROS_FATAL("SytemBehavior %s willBecomeActive returned false. THIS MUST NOT HAPPEN!", newBehavior->getName().c_str());
00204                 }
00205         }
00206 
00207         
00208         activeBehaviorPtr->willBecomeInActive( seController.getLastState(), *newBehavior );
00209 
00210         ROS_INFO_STREAM("Behavior: Switching from " << activeBehaviorPtr->getName() << " to " << newBehavior->getName());
00211 
00212         
00213         
00214         Behavior* oldBehavior = activeBehaviorPtr;
00215         activeBehaviorPtr = newBehavior;
00216         
00217 
00218         transitionState = TransitionState::Creation;
00219         
00220 
00221 
00222         
00223         behaviorController.activeBehaviorChanged();
00224         
00225         activeBehaviorPtr->didBecomeActive( seController.getLastState(), *oldBehavior );
00226 
00227         transitionState = TransitionState::Active;
00228 
00229         oldBehavior->didBecomeInActive( seController.getLastState(), *activeBehaviorPtr );
00230 
00231         
00232         behaviorChangeMutex.unlock();
00233 }
00234 
00235 Behavior* ActiveBehaviorContainer::getActive() const
00236 {
00237         return activeBehaviorPtr;
00238 }
00239 
00240 
00241 }