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 "flyer_controller/control_mode.h"
00035 #include "flyer_controller/control_modes.h"
00036
00037 namespace flyer_controller
00038 {
00039
00040 std::string ControlMode::stateToString(ControlModeTypes::ControlModeState t)
00041 {
00042 switch (t)
00043 {
00044 case ControlModeTypes::OFF:
00045 return "OFF";
00046 case ControlModeTypes::ERROR:
00047 return "ERROR";
00048 case ControlModeTypes::IDLE:
00049 return "IDLE";
00050 case ControlModeTypes::STANDBY:
00051 return "STANDBY";
00052 case ControlModeTypes::ACTIVE:
00053 return "ACTIVE";
00054 }
00055 return "Unknown";
00056 }
00057
00058 void ControlMode::onInit()
00059 {
00060 NODELET_INFO("ControlMode onInit() called");
00061 nh = getNodeHandle();
00062 nh_priv = getPrivateNodeHandle();
00063
00064
00065 diag_updater.add(getName() + " status", this, &ControlMode::diagnostics);
00066 diag_updater.setHardwareID("none");
00067 diag_updater.force_update();
00068
00069
00070 nh_priv.param("status_report_rate", status_report_rate, status_report_rate);
00071 nh_priv.param("control_output_rate", control_output_rate, control_output_rate);
00072 nh_priv.param("event_driven", event_driven, event_driven);
00073 CHECK_PARAMETER((status_report_rate > 0), "parameter value out of range");
00074 CHECK_PARAMETER((control_output_rate > 0), "parameter value out of range");
00075
00076
00077 control_mode_status_pub = nh_priv.advertise<control_mode_status> ("status", 1, true);
00078 }
00079
00080 ControlMode::ControlMode() :
00081 status_report_rate(5), control_output_rate(10),
00082 event_driven(false),
00083 state(ControlModeTypes::OFF), ready(false), got_first_state(false), seen_max_alt(false), seen_min_alt(false),
00084 got_first_joy(false), latest_alt_cmd(0), state_updated(false), state_count(0), control_count(0)
00085 {
00086 }
00087
00089 void ControlMode::diagnostics(diagnostic_updater::DiagnosticStatusWrapper& stat)
00090 {
00091 int status;
00092 status = ((state != ControlModeTypes::ERROR) ? diagnostic_msgs::DiagnosticStatus::OK
00093 : diagnostic_msgs::DiagnosticStatus::ERROR);
00094 stat.summary(status, stateToString(state));
00095 stat.add("ready", ready);
00096 stat.add("info", info);
00097 stat.add("state_count", state_count);
00098 stat.add("control_count", control_count);
00099 }
00100
00101 void ControlMode::requestRegistration(const std::string& mode_name, double wait_time)
00102 {
00103 reg_timer = nh.createTimer(ros::Duration(0.01),
00104 boost::bind(&ControlMode::requestRegistration2, this, _1, mode_name, wait_time), true);
00105 }
00106
00107 void ControlMode::requestRegistration2(const ros::TimerEvent& event, const std::string& mode_name, double wait_time)
00108 {
00109
00110 NODELET_INFO("Waiting %f seconds before trying to register..", wait_time);
00111 ros::Duration d(wait_time);
00112 d.sleep();
00113 NODELET_INFO("Waiting for controller/control_modes service...");
00114 info = "Waiting for controller/control_mode service...";
00115 ros::service::waitForService("controller/control_modes");
00116 info = "registering service...";
00117 control_modes register_service;
00118 register_service.request.request = "register " + mode_name + " " + getName();
00119 bool registered = ros::service::call("controller/control_modes", register_service);
00120 if (registered)
00121 {
00122 if (register_service.response.response == "success")
00123 {
00124 NODELET_INFO_STREAM("Successfully registered control mode " << mode_name);
00125 info = "control mode registered";
00126 startDataFlow();
00127 }
00128 else
00129 {
00130 NODELET_ERROR_STREAM ("Control mode registration failed, response: '" << register_service.response.response
00131 << "', reason: '" << register_service.response.reason << "'");
00132 state = ControlModeTypes::ERROR;
00133 info = "registration failed";
00134 }
00135 }
00136 else
00137 {
00138 NODELET_ERROR("Control mode registration service call failed");
00139 state = ControlModeTypes::ERROR;
00140 info = "registration service call failed";
00141 }
00142 }
00143
00144 ControlMode::~ControlMode()
00145 {
00146 NODELET_INFO("Destructor called");
00147 }
00148
00149 void ControlMode::startDataFlow()
00150 {
00151
00152
00153 output_pub = nh_priv.advertise<control_mode_output> ("output", 10);
00154
00155 control_mode_cmd_sub = nh_priv.subscribe("cmd", 500, &ControlMode::controlModeCmdCallback, this);
00156 opercmd_sub = nh.subscribe("teleop_flyer/operator_cmds", 10, &ControlMode::operCmdCallback, this);
00157 state_sub = nh.subscribe("odom", 2, &ControlMode::stateCallback, this);
00158
00159 if (not event_driven)
00160 output_controls_timer = nh.createTimer(ros::Duration(1 / control_output_rate),
00161 &ControlMode::outputControlTimerCallback, this);
00162 report_status_timer = nh.createTimer(ros::Duration(1 / status_report_rate), &ControlMode::reportStatusTimerCallback,
00163 this);
00164
00165 state = ControlModeTypes::IDLE;
00166 info = "data flow started";
00167
00168 }
00169
00170 void ControlMode::controlModeCmdCallback(const control_mode_cmdConstPtr& msg)
00171 {
00172 NODELET_DEBUG_STREAM("Heard command: " << msg->cmd);
00173 if (msg->cmd == "mode idle")
00174 {
00175 state = ControlModeTypes::IDLE;
00176 info = "";
00177 }
00178 else if (msg->cmd == "mode standby")
00179 {
00180 state = ControlModeTypes::STANDBY;
00181 info = "";
00182 }
00183 else if (msg->cmd == "mode active")
00184 {
00185 if (state == ControlModeTypes::STANDBY)
00186 {
00187 state = ControlModeTypes::ACTIVE;
00188 info = "";
00189 }
00190 else
00191 {
00192 NODELET_ERROR("Invalid transition");
00193 }
00194 }
00195 else
00196 {
00197 NODELET_ERROR_STREAM("Command unknown: " << msg->cmd);
00198 }
00199 }
00200
00201 void ControlMode::operCmdCallback(const starmac_msgs::OperatorCommandsConstPtr& msg)
00202 {
00203
00204 latest_opercmd = *msg;
00205 if (not got_first_joy)
00206 got_first_joy = true;
00207 }
00208
00209 void ControlMode::stateCallback(const nav_msgs::OdometryConstPtr& msg)
00210 {
00211
00212 if (!got_first_state)
00213 got_first_state = true;
00214 latest_state = *msg;
00215 state_updated = true;
00216 state_count++;
00217 if (event_driven)
00218 {
00219 control_count++;
00220 outputControl();
00221 }
00222
00223 }
00224
00225 void ControlMode::reportStatusTimerCallback(const ros::TimerEvent& e)
00226 {
00227 control_mode_statusPtr msg(new control_mode_status);
00228
00229 msg->state = state;
00230 msg->info = info;
00231 msg->ready = ready;
00232 control_mode_status_pub.publish(msg);
00233 diag_updater.update();
00234 }
00235
00236 void ControlMode::outputControlTimerCallback(const ros::TimerEvent& e)
00237 {
00238
00239 if (not event_driven)
00240 {
00241 control_count++;
00242 outputControl();
00243 }
00244 else
00245 ROS_FATAL("Code should not get here! Do some debugging!");
00246 }
00247
00248 void ControlMode::outputControl()
00249 {
00250 control_mode_outputPtr control_out(new control_mode_output);
00251 switch (state)
00252 {
00253 case ControlModeTypes::STANDBY:
00254 case ControlModeTypes::ACTIVE:
00255 output_pub.publish(control_out);
00256 break;
00257 default:
00258 break;
00259 }
00260
00261 }
00262
00263 }
00264