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 }