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 #include <ros/ros.h>
00035 #include <nodelet/nodelet.h>
00036 #include <pluginlib/class_list_macros.h>
00037 #include <diagnostic_updater/diagnostic_updater.h>
00038 #include <map>
00039 #include <string>
00040 #include <set>
00041 #include <algorithm>
00042 #include "topic_tools/MuxAdd.h"
00043 #include "topic_tools/MuxSelect.h"
00044 #include "topic_tools/MuxList.h"
00045 
00046 #include "flyer_controller/control_modes.h"
00047 #include "flyer_controller/control_mode_cmd.h"
00048 #include "flyer_controller/control_mode_status.h"
00049 #include "flyer_controller/controller_status.h"
00050 #include "flyer_controller/controller_cmd.h"
00051 #include <boost/algorithm/string.hpp>
00052 
00053 using namespace std;
00054 
00055 namespace flyer_controller
00056 {
00057 
00058 namespace ControllerTypes
00059 {
00060 enum ControllerStates
00061 {
00062   ERROR = 0, OFF = 1, INITIALIZE = 2, STANDBY = 3, OPERATIONAL = 4
00063 };
00064 typedef ControllerStates ControllerState;
00065 
00066 }
00067 
00068 using namespace ControllerTypes;
00069 
00070 class Controller : public nodelet::Nodelet
00071 {
00072 private:
00073   ros::NodeHandle nh;
00074   ros::NodeHandle nh_priv;
00075   
00076   string initial_active_mode;
00077   string initial_standby_mode;
00078   double mainloop_rate;
00079   
00080   ros::Publisher status_pub;
00081   map<string, ros::Publisher> mode_cmd_pubs;
00082   
00083   ros::Subscriber cmd_sub;
00084   map<string, ros::Subscriber> mode_status_subs;
00085   
00086   ros::Timer mainloop_timer;
00087   
00088   diagnostic_updater::Updater diag_updater;
00089 
00090   
00091   ros::ServiceServer control_modes_service;
00092   
00093   string current_mode;
00094   string standby_mode;
00095   set<string> registered_modes;
00096   map<string, string> node_mode_map; 
00097   map<string, string> mode_node_map; 
00098   map<string, control_mode_status> latest_mode_status;
00099   ControllerState state;
00100   string info;
00101   bool command_pending;
00102   string pending_command;
00103   boost::mutex mainloop_mutex;
00104   boost::mutex register_mutex;
00105 
00106   
00107 public:
00108   Controller() :
00109     initial_active_mode("idle"), initial_standby_mode("attitude"), mainloop_rate(5.0), diag_updater(), state(OFF),
00110         info(""), command_pending(false), pending_command("")
00111   {
00112   }
00113 
00114   void onInit()
00115   {
00116 
00117     nh = getMTNodeHandle();
00118     nh_priv = getMTPrivateNodeHandle();
00119 
00120     NODELET_INFO("controller.cpp onInit() begin");
00121 
00122     
00123     diag_updater.add("Controller Status", this, &Controller::diagnostics);
00124     diag_updater.setHardwareID("none");
00125     diag_updater.force_update();
00126     
00127     nh_priv.param("initial_active_mode", initial_active_mode, initial_active_mode);
00128     nh_priv.param("initial_standby_mode", initial_standby_mode, initial_standby_mode);
00129     nh_priv.param("mainloop_rate", mainloop_rate, mainloop_rate);
00130     
00131     status_pub = nh_priv.advertise<controller_status> ("status", 1, true);
00132     
00133     cmd_sub = nh_priv.subscribe("cmd", 10, &Controller::commandCallback, this);
00134     
00135     control_modes_service = nh_priv.advertiseService("control_modes", &Controller::controlModesServiceCallback, this);
00136 
00137     
00138     mainloop_timer = nh.createTimer(ros::Duration(1 / mainloop_rate), &Controller::mainLoopCallback, this);
00139 
00140     state = INITIALIZE;
00141 
00142     NODELET_INFO("controller.cpp onInit() done");
00143 
00144   }
00145 
00146   std::string stateToString(ControllerTypes::ControllerState t)
00147   {
00148     switch (t)
00149     {
00150       case ControllerTypes::OFF:
00151         return "OFF";
00152       case ControllerTypes::ERROR:
00153         return "ERROR";
00154       case ControllerTypes::INITIALIZE:
00155         return "INITIALIZE";
00156       case ControllerTypes::STANDBY:
00157         return "STANDBY";
00158       case ControllerTypes::OPERATIONAL:
00159         return "OPERATIONAL";
00160     }
00161     return "Unknown";
00162   }
00163 
00164 private:
00165 
00166   void diagnostics(diagnostic_updater::DiagnosticStatusWrapper& stat)
00167   {
00168     int status;
00169     status = ((state != ERROR) ? diagnostic_msgs::DiagnosticStatus::OK : diagnostic_msgs::DiagnosticStatus::ERROR);
00170     stat.summary(status, stateToString(state));
00171     stat.add("info", info);
00172     stat.add("registered modes", registered_modes.size());
00173     stat.add("current mode", current_mode);
00174     stat.add("standby mode", standby_mode);
00175   }
00176 
00177   void commandCallback(const controller_cmdConstPtr& msg)
00178   {
00179     
00180     
00181     ROS_INFO_STREAM("Command received: " << msg->cmd);
00182     if (command_pending)
00183     {
00184       ROS_ERROR("Command already pending - new command ignored");
00185     }
00186     else
00187     {
00188       command_pending = true;
00189       pending_command = msg->cmd;
00190     }
00191   }
00192 
00193   bool controlModesServiceCallback(control_modes::Request& request, control_modes::Response& response)
00194   {
00195     boost::mutex::scoped_lock lock(register_mutex);
00196     ROS_INFO_STREAM("Service call received. Request was: " << request.request);
00197     vector<string> words;
00198     boost::split(words, request.request, boost::is_any_of(" "));
00199 
00200     if (words.size() > 0)
00201     {
00202       if (words[0] == "register")
00203       {
00204         if (words.size() != 3)
00205         {
00206           ROS_ERROR("Invalid request");
00207           response.response = "failure";
00208           response.reason = "invalid number of parameters";
00209         }
00210         else
00211         {
00212           string mode_name = words[1];
00213           string mode_node = words[2];
00214           if (registered_modes.count(mode_name) > 0)
00215           {
00216             ROS_ERROR_STREAM("A control mode named " << mode_name << " has already been registered.");
00217             response.response = "failure";
00218             response.reason = "control mode already registered";
00219           }
00220           else
00221           {
00222             ROS_INFO_STREAM("Registering control mode, name: " << mode_name << ", node: " << mode_node);
00223             mode_cmd_pubs[mode_name] = nh.advertise<control_mode_cmd> (mode_node + "/cmd", 1, true);
00224             
00225             
00226             
00227             mode_status_subs[mode_name]
00228                 = nh.subscribe<control_mode_status> (
00229                                                      mode_node + "/status",
00230                                                      10,
00231                                                      boost::bind(&Controller::controlModesStatusCallback, this, _1,
00232                                                                  mode_node));
00233             registered_modes.insert(mode_name);
00234             node_mode_map[nh.resolveName(mode_node)] = mode_name;
00235             mode_node_map[mode_name] = nh.resolveName(mode_node);
00236             response.response = "success";
00237           }
00238         }
00239       }
00240     }
00241     else
00242     {
00243       response.response = "failure";
00244       response.reason = "invalid request";
00245     }
00246     ROS_INFO_STREAM("Completed service call. Request was: " << request.request);
00247 
00248     return true; 
00249   }
00250 
00251   void controlModesStatusCallback(const flyer_controller::control_mode_statusConstPtr& msg, string source) 
00252   {
00253     
00254     
00255     
00256     latest_mode_status[node_mode_map[source]] = *msg; 
00257   }
00258 
00259   void mainLoopCallback(const ros::TimerEvent& e)
00260   {
00261     boost::mutex::scoped_lock lock(mainloop_mutex);
00262 
00263     diag_updater.update();
00264 
00265     switch (state)
00266     {
00267       case ERROR:
00268         break;
00269       case OFF:
00270         break;
00271       case INITIALIZE:
00272         execute_INITIALIZE();
00273         break;
00274       case STANDBY:
00275         execute_STANDBY();
00276         break;
00277       case OPERATIONAL:
00278         execute_OPERATIONAL();
00279         break;
00280       default:
00281         break;
00282     }
00283     controller_statusPtr status_msg(new controller_status);
00284     status_msg->state = state;
00285     status_msg->info = info;
00286     status_msg->active_mode = current_mode;
00287     status_msg->header.stamp = e.current_real;
00288     map<string, control_mode_status>::iterator it;
00289     getStandbyModes(status_msg->standby_modes);
00290     status_pub.publish(status_msg);
00291   }
00292 
00293   void getStandbyModes(vector<string>& modes)
00294   {
00295     map<string, control_mode_status>::iterator it;
00296     modes.clear();
00297     for (it = latest_mode_status.begin(); it != latest_mode_status.end(); it++)
00298     {
00299       if ((*it).second.state == control_mode_status::STATE_STANDBY)
00300       {
00301         modes.push_back((*it).first);
00302       }
00303     }
00304 
00305   }
00306 
00307   void execute_INITIALIZE()
00308   {
00309     
00310     
00311     static bool initialize_waiting_modes_mux = true, initialize_transitioned_active_mode = false,
00312                 initialize_transitioned_standby_mode = false, initialize_active_mode_in_standby = false,
00313                 initialize_standby_mode_in_standby = false, initialize_active_muxed = false, initialize_standby_muxed =
00314                     false;
00315     enum InitializePhases
00316     {
00317       INITIALIZE_WAIT_MODES_MUX, INITIALIZE_TRANSITION_ACTIVE, INITIALIZE_TRANSITION_STANDBY,
00318       INITIALIZE_WAIT_STANDBY_TALKBACK
00319     };
00320 
00321     static InitializePhases init_phase = INITIALIZE_WAIT_MODES_MUX;
00322 
00323     
00324     switch (init_phase)
00325     {
00326       case INITIALIZE_WAIT_MODES_MUX:
00327       {
00328 
00329       }
00330         break;
00331     }
00332 
00333     if (initialize_waiting_modes_mux)
00334     {
00335       if (registered_modes.count(initial_active_mode) > 0 && registered_modes.count(initial_standby_mode) > 0
00336           && ros::service::exists("controller_mux/add", false))
00337       {
00338         ROS_INFO("Initial modes have registered");
00339         info = "got modes and mux";
00340         diag_updater.force_update();
00341         initialize_waiting_modes_mux = false;
00342       }
00343       else
00344       {
00345         info = "waiting for modes and mux";
00346       }
00347     }
00348     else 
00349     {
00350       topic_tools::MuxAdd mux_add_srv;
00351       if (!initialize_transitioned_active_mode) 
00352       {
00353         control_mode_cmdPtr active_to_standby_msg(new control_mode_cmd);
00354         active_to_standby_msg->cmd = "mode standby";
00355         mode_cmd_pubs[initial_active_mode].publish(active_to_standby_msg);
00356         initialize_transitioned_active_mode = true;
00357       }
00358       else
00359       {
00360         if (!initialize_active_muxed)
00361         {
00362           mux_add_srv.request.topic = "control_mode_" + initial_active_mode + "/output";
00363           if (ros::service::call("controller_mux/add", mux_add_srv))
00364           {
00365             initialize_active_muxed = true;
00366           }
00367         }
00368       }
00369       if (!initialize_transitioned_standby_mode) 
00370       {
00371         control_mode_cmdPtr standby_to_standby_msg(new control_mode_cmd);
00372         standby_to_standby_msg->cmd = "mode standby";
00373         mode_cmd_pubs[initial_standby_mode].publish(standby_to_standby_msg);
00374         initialize_transitioned_standby_mode = true;
00375       }
00376       else
00377       {
00378         if (!initialize_standby_muxed)
00379         {
00380           mux_add_srv.request.topic = "control_mode_" + initial_standby_mode + "/output";
00381           if (ros::service::call("controller_mux/add", mux_add_srv))
00382           {
00383             initialize_standby_muxed = true;
00384           }
00385         }
00386       }
00387       if (initialize_transitioned_active_mode && initialize_active_muxed && initialize_transitioned_standby_mode
00388           && initialize_standby_muxed)
00389       {
00390         info = "waiting for STANDBY talkback";
00391         
00392         if (latest_mode_status[initial_active_mode].state == control_mode_status::STATE_STANDBY
00393             && latest_mode_status[initial_standby_mode].state == control_mode_status::STATE_STANDBY)
00394         {
00395           ROS_INFO_STREAM("Initial active and standby modes reporting STANDBY state, controller going to STANDBY");
00396           state = STANDBY;
00397           info = "";
00398           current_mode = initial_active_mode;
00399           standby_mode = initial_standby_mode;
00400           diag_updater.force_update();
00401         }
00402       }
00403     }
00404   }
00405 
00406   void execute_STANDBY()
00407   {
00408     
00409     
00410     
00411     
00412     
00413     
00414 
00415     
00416     static bool standby_entering_operational = false, standby_commanded_active_mode = false,
00417                 standby_mux_selected_active = false;
00418 
00419     
00420     if (command_pending)
00421     {
00422       if (pending_command == "mode operational" and !standby_entering_operational)
00423       {
00424         ROS_INFO("Entering OPERATIONAL");
00425         command_pending = false;
00426         pending_command = "";
00427         info = "entering OPERATIONAL";
00428         diag_updater.force_update();
00429         standby_entering_operational = true;
00430       }
00431       else
00432       {
00433         ROS_ERROR("Invalid command in STANDBY mode");
00434         command_pending = false;
00435         pending_command = "";
00436       }
00437     }
00438     if (standby_entering_operational)
00439     {
00440       if (!standby_commanded_active_mode)
00441       {
00442         
00443         control_mode_cmdPtr current_to_active_msg(new control_mode_cmd);
00444         current_to_active_msg->cmd = "mode active";
00445         mode_cmd_pubs[current_mode].publish(current_to_active_msg);
00446         standby_commanded_active_mode = true;
00447         info = "commanded current mode to ACTIVE";
00448       }
00449       else
00450       {
00451         if (!standby_mux_selected_active)
00452         {
00453           topic_tools::MuxSelect mux_sel_srv;
00454           mux_sel_srv.request.topic = mode_node_map[current_mode] + "/output";
00455           ros::service::call("controller_mux/select", mux_sel_srv);
00456           standby_mux_selected_active = true;
00457           info = "requested mux select: " + mode_node_map[current_mode] + "/output";
00458         }
00459         else
00460         {
00461           
00462         }
00463         
00464         if (latest_mode_status[current_mode].state == control_mode_status::STATE_ACTIVE)
00465         {
00466           state = OPERATIONAL;
00467           info = "current mode reporting ACTIVE";
00468           diag_updater.force_update();
00469         }
00470       }
00471     }
00472   }
00473 
00474   enum OPERATIONAL_Substate
00475   {
00476     OP_READY, OP_ACTIVATING_MODE, OP_STANDBYING_MODE
00477   };
00478 
00479   void execute_OPERATIONAL()
00480   {
00481     
00482     
00483     
00484     
00485     
00486     
00487     
00488     
00489     static OPERATIONAL_Substate substate = OP_READY;
00490     static OPERATIONAL_Substate prev_substate = OP_READY;
00491     bool reset = true;
00492     string new_mode = "";
00493 
00494     if (substate == OP_READY)
00495     {
00496       execute_OPERATIONAL_READY(substate, new_mode);
00497     }
00498     if (substate != prev_substate)
00499     {
00500       ROS_DEBUG_STREAM("Operational substate changed: " << prev_substate << " -> " << substate);
00501       reset = true;
00502     }
00503     else
00504     {
00505       reset = false;
00506     }
00507 
00508     prev_substate = substate;
00509 
00510     bool substate_completed = false;
00511     switch (substate)
00512     {
00513       case OP_READY:
00514         break;
00515       case OP_ACTIVATING_MODE:
00516         substate_completed = execute_OPERATIONAL_ACTIVATING_MODE(reset, new_mode);
00517         break;
00518       case OP_STANDBYING_MODE:
00519         substate_completed = execute_OPERATIONAL_STANDBYING_MODE(reset, new_mode);
00520         break;
00521     }
00522     if (substate_completed)
00523     {
00524       substate = OP_READY;
00525     }
00526 
00527   }
00528 
00529   void execute_OPERATIONAL_READY(OPERATIONAL_Substate& substate, string& new_mode)
00530   {
00531     
00532     
00533     
00534 
00535     if (command_pending)
00536     {
00537       bool valid = false;
00538       string reason = "";
00539       vector<string> words;
00540       boost::split(words, pending_command, boost::is_any_of(" "));
00541       if (words.size() > 0)
00542       {
00543         if (words[0] == "control_mode")
00544         
00545         
00546         
00547         {
00548           if (words.size() == 3)
00549           {
00550             if (words[1] == "to_active")
00551             {
00552               new_mode = words[2];
00553               if (new_mode == current_mode)
00554               {
00555                 reason = ": current_mode already " + new_mode;
00556               }
00557               else
00558               {
00559                 vector<string>::iterator it;
00560                 vector<string> standby_modes;
00561                 getStandbyModes(standby_modes);
00562                 if (find(standby_modes.begin(), standby_modes.end(), new_mode) != standby_modes.end())
00563                 {
00564                   valid = true;
00565                   info = "mode change accepted";
00566                   substate = OP_ACTIVATING_MODE;
00567                 }
00568                 else
00569                 {
00570                   ROS_ERROR_STREAM("Mode " << new_mode << " is not in STANDBY, cannot activate");
00571                 }
00572               }
00573             }
00574             else if (words[1] == "to_standby")
00575             {
00576               new_mode = words[2];
00577               valid = true;
00578               substate = OP_STANDBYING_MODE;
00579             }
00580             else if (words[1] == "to_idle")
00581             {
00582               ROS_ERROR("control_mode to_idle commands not yet implemented");
00583             }
00584           }
00585         }
00586       }
00587 
00588       if (!valid)
00589       {
00590         ROS_ERROR_STREAM("Invalid command" << reason);
00591         info = "mode change rejected";
00592       }
00593 
00594       
00595       command_pending = false;
00596       pending_command = "";
00597     }
00598 
00599   }
00600 
00601   bool execute_OPERATIONAL_ACTIVATING_MODE(bool reset, const string mode_to_activate)
00602   {
00603     enum SequenceStatus
00604     {
00605       MODE_CHANGE_ACCEPTED, WAITING_NEW_ACTIVE_TALKBACK, WAITING_OLD_STANDBY_TALKBACK, FINISHED
00606     };
00607     static SequenceStatus sequence_status = FINISHED;
00608     static string new_mode;
00609     ROS_DEBUG_STREAM(
00610                      "execute_OPERATIONAL_ACTIVATING_MODE, reset=" << reset << ", new_mode=" << new_mode
00611                          << ", sequence_status=" << sequence_status);
00612     if (reset)
00613     {
00614       sequence_status = MODE_CHANGE_ACCEPTED;
00615       new_mode = mode_to_activate;
00616     }
00617 
00618     switch (sequence_status)
00619     {
00620       case MODE_CHANGE_ACCEPTED:
00621       {
00622         if (latest_mode_status[new_mode].ready)
00623         {
00624           
00625           topic_tools::MuxSelect mux_sel_srv;
00626           mux_sel_srv.request.topic = mode_node_map[new_mode] + "/output";
00627           ros::service::call("controller_mux/select", mux_sel_srv);
00628           
00629           control_mode_cmdPtr new_to_active_msg(new control_mode_cmd);
00630           new_to_active_msg->cmd = "mode active";
00631           mode_cmd_pubs[new_mode].publish(new_to_active_msg);
00632           info = "mux selected and commanded current mode to ACTIVE - waiting to see ACTIVE";
00633           sequence_status = WAITING_NEW_ACTIVE_TALKBACK;
00634         }
00635         else
00636         {
00637           ROS_ERROR_STREAM("mode " << new_mode << " reporting not ready to go ACTIVE, mode transition cancelled");
00638           info = "mode change failed -- see log";
00639           sequence_status = FINISHED;
00640         }
00641       }
00642         break;
00643       case WAITING_NEW_ACTIVE_TALKBACK:
00644       {
00645         if (latest_mode_status[new_mode].state == control_mode_status::STATE_ACTIVE)
00646         {
00647           
00648           control_mode_cmdPtr old_to_standby_msg(new control_mode_cmd);
00649           old_to_standby_msg->cmd = "mode standby";
00650           mode_cmd_pubs[current_mode].publish(old_to_standby_msg);
00651           info = "commanded current mode to STANDBY - waiting to see STANDBY";
00652           sequence_status = WAITING_OLD_STANDBY_TALKBACK;
00653         }
00654       }
00655         break;
00656       case WAITING_OLD_STANDBY_TALKBACK:
00657       {
00658         if (latest_mode_status[current_mode].state == control_mode_status::STATE_STANDBY)
00659         {
00660           info = "old mode in STANDBY -- mode transition complete!";
00661           standby_mode = current_mode;
00662           current_mode = new_mode;
00663           sequence_status = FINISHED;
00664         }
00665       }
00666         break;
00667       case FINISHED:
00668       {
00669         ROS_ERROR("The code shouldn't get here--please debug!");
00670       }
00671         break;
00672     }
00673 
00674     return (sequence_status == FINISHED);
00675   }
00676 
00677   bool execute_OPERATIONAL_STANDBYING_MODE(bool reset, const string mode_to_standby)
00678   {
00679     enum SequenceStatus
00680     {
00681       MODE_CHANGE_ACCEPTED, WAITING_STANDBY_TALKBACK, ADDING_MUXER_INPUT, WAITING_MUXER_TALKBACK, FINISHED
00682     };
00683     static SequenceStatus sequence_status = FINISHED;
00684     static string new_mode;
00685     static int muxer_talkback_wait_cycles = 10;
00686 
00687     ROS_DEBUG_STREAM(
00688                      "execute_OPERATIONAL_STANDBYING_MODE, reset=" << reset << ", new_mode=" << new_mode
00689                          << ", sequence_status=" << sequence_status);
00690     if (reset)
00691     {
00692       sequence_status = MODE_CHANGE_ACCEPTED;
00693       new_mode = mode_to_standby;
00694       muxer_talkback_wait_cycles = 10;
00695     }
00696 
00697     switch (sequence_status)
00698     {
00699       case MODE_CHANGE_ACCEPTED:
00700       {
00701         
00702         control_mode_cmdPtr new_to_standby_msg(new control_mode_cmd);
00703         new_to_standby_msg->cmd = "mode standby";
00704         mode_cmd_pubs[new_mode].publish(new_to_standby_msg);
00705         info = "mode " + new_mode + " commanded to STANDBY - waiting to see STANDBY";
00706         sequence_status = WAITING_STANDBY_TALKBACK;
00707       }
00708         break;
00709       case WAITING_STANDBY_TALKBACK:
00710       {
00711         if (latest_mode_status[new_mode].state == control_mode_status::STATE_STANDBY)
00712         {
00713           info = "mode in STANDBY - adding to muxer";
00714           sequence_status = ADDING_MUXER_INPUT;
00715         }
00716       }
00717         break;
00718       case ADDING_MUXER_INPUT:
00719       {
00720         topic_tools::MuxAdd mux_add_srv;
00721         mux_add_srv.request.topic = "control_mode_" + new_mode + "/output";
00722         ros::service::call("controller_mux/add", mux_add_srv);
00723         info = "waiting for muxer talkback...";
00724         sequence_status = WAITING_MUXER_TALKBACK;
00725       }
00726         break;
00727       case WAITING_MUXER_TALKBACK:
00728       {
00729         topic_tools::MuxList mux_list_srv;
00730         ros::service::call("controller_mux/list", mux_list_srv);
00731         vector<string>::iterator it;
00732         string full_topic_name = ros::names::resolve("control_mode_" + new_mode + "/output");
00733         if (find(mux_list_srv.response.topics.begin(), mux_list_srv.response.topics.end(), full_topic_name)
00734             != mux_list_srv.response.topics.end())
00735         {
00736           sequence_status = FINISHED;
00737           info = "muxer has " + full_topic_name + " in its input list - mode is in STANDBY";
00738         }
00739         else
00740         {
00741           muxer_talkback_wait_cycles--;
00742         }
00743         if (muxer_talkback_wait_cycles <= 0)
00744         {
00745           ROS_ERROR_STREAM(
00746                            "Muxer still doesn't have topic " << full_topic_name << " after " << (10
00747                                - muxer_talkback_wait_cycles) << "tries...");
00748         }
00749       }
00750         break;
00751       case FINISHED:
00752       {
00753         ROS_ERROR("The code shouldn't get here--please debug!");
00754       }
00755         break;
00756     }
00757 
00758     return (sequence_status == FINISHED);
00759   }
00760 
00761 }; 
00762 PLUGINLIB_DECLARE_CLASS(flyer_controller, Controller, flyer_controller::Controller, nodelet::Nodelet)
00763 ;
00764 
00765 } 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773 
00774 
00775