Go to the documentation of this file.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/hover_modes.h"
00036
00037 #include "flyer_controller/control_mode_hover_info.h"
00038
00039 namespace flyer_controller
00040 {
00041 class ControlModeHover : public HoverMode
00042 {
00043 protected:
00044
00045 double pitch_deadband;
00046 double roll_deadband;
00047 double yaw_deadband;
00048
00049 double max_yaw_rate_cmd;
00050 double waypoint_speed;
00051 bool external_command_frame;
00052 double external_frame_heading;
00053
00054
00055 ros::Time last_control_output_time;
00056 bool first_joystick;
00057 bool moving_hover_point;
00058 bool adjusting_yaw;
00059
00060 public:
00061 ControlModeHover() :
00062 HoverMode("hover"),
00063 pitch_deadband(0.05), roll_deadband(0.05), yaw_deadband(0.1),
00064 max_yaw_rate_cmd(10), waypoint_speed(0.25), external_command_frame(false), external_frame_heading(0),
00065 first_joystick(true), moving_hover_point(false), adjusting_yaw(false)
00066 {
00067 }
00068
00069 void onInit()
00070 {
00071 HoverMode::onInit();
00072 NODELET_WARN("Joystick must be properly calibrated using jscal.. have you done this?");
00073
00074 nh_priv.param("pitch_deadband", pitch_deadband, pitch_deadband);
00075 nh_priv.param("roll_deadband", roll_deadband, roll_deadband);
00076 nh_priv.param("yaw_deadband", yaw_deadband, yaw_deadband);
00077 CHECK_PARAMETER((pitch_deadband >= 0) and (pitch_deadband <= 1), "parameter value out of range");
00078 CHECK_PARAMETER((roll_deadband >= 0) and (roll_deadband <= 1), "parameter value out of range");
00079 CHECK_PARAMETER((yaw_deadband >= 0) and (yaw_deadband <= 1), "parameter value out of range");
00080 nh_priv.param("max_yaw_rate_cmd", max_yaw_rate_cmd, max_yaw_rate_cmd);
00081 CHECK_PARAMETER(max_yaw_rate_cmd >= 0, "parameter value out of range");
00082 nh_priv.param("waypoint_speed", waypoint_speed, waypoint_speed);
00083 nh_priv.param("external_command_frame", external_command_frame, external_command_frame);
00084 nh_priv.param("external_frame_heading", external_frame_heading, external_frame_heading);
00085 }
00086
00087 bool parseControlModeCmdDerived(const string cmd)
00088 {
00089 vector<string> words;
00090 boost::split(words, cmd, boost::is_any_of(" "));
00091 int nw = words.size();
00092 if (nw > 0)
00093 {
00094 if (words[0] == "adjust")
00095 {
00096 if ((nw == 3) and (words[1] == "hover_point"))
00097 {
00098 if (words[2] == "on")
00099 {
00100 if (not moving_hover_point)
00101 {
00102 moving_hover_point = true;
00103 NODELET_INFO("Hover point adjustment by joystick enabled");
00104 }
00105 else
00106 NODELET_ERROR("Hover point adjustment already enabled");
00107 }
00108 else if (words[2] == "off")
00109 {
00110 if (moving_hover_point)
00111 {
00112 moving_hover_point = false;
00113 NODELET_INFO("Hover point adjustment by joystick disabled");
00114 }
00115 else
00116 NODELET_ERROR("Hover point adjustment already disabled");
00117
00118 }
00119 else
00120 NODELET_ERROR_STREAM("Invalid command '" << cmd << "'");
00121 }
00122 else if ((nw == 3) and (words[1] == "yaw"))
00123 {
00124 if (words[2] == "on")
00125 {
00126 if (not adjusting_yaw)
00127 {
00128 adjusting_yaw = true;
00129 NODELET_INFO("Yaw adjustment by joystick enabled");
00130 }
00131 else
00132 NODELET_ERROR("Yaw adjustment already enabled");
00133 }
00134 else if (words[2] == "off")
00135 {
00136 if (adjusting_yaw)
00137 {
00138 NODELET_INFO("Yaw adjustment by joystick disabled");
00139 adjusting_yaw = false;
00140 }
00141 else
00142 NODELET_ERROR("Yaw adjustment already disabled");
00143 }
00144 else
00145 {
00146 NODELET_ERROR_STREAM("Invalid command '" << cmd << "'");
00147 }
00148 }
00149 else
00150 {
00151 NODELET_ERROR_STREAM("Invalid command '" << cmd << "'");
00152 }
00153 }
00154 else
00155 return false;
00156 }
00157 else
00158 return false;
00159
00160 return true;
00161 }
00162
00163
00164
00165 void outputControl()
00166 {
00167 ros::Time now_time = ros::Time::now();
00168 if (first_joystick)
00169 {
00170 last_control_output_time = now_time;
00171 first_joystick = false;
00172 return;
00173 }
00174 double dt = (now_time - last_control_output_time).toSec();
00175
00176 if (moving_hover_point)
00177 {
00178
00179 double cos_ang, sin_ang;
00180 if (external_command_frame)
00181 {
00182 cos_ang = cos(angles::from_degrees(external_frame_heading));
00183 sin_ang = sin(angles::from_degrees(external_frame_heading));
00184 }
00185 else
00186 {
00187 double current_yaw, current_pitch, current_roll;
00188 odom_msg_to_ypr(boost::make_shared<nav_msgs::Odometry>(latest_state), current_yaw, current_pitch, current_roll);
00189 cos_ang = cos(current_yaw);
00190 sin_ang = sin(current_yaw);
00191 }
00192 double north_cmd_normalized = -sin_ang * latest_opercmd.roll_cmd - cos_ang * latest_opercmd.pitch_cmd;
00193 double east_cmd_normalized = cos_ang * latest_opercmd.roll_cmd - sin_ang * latest_opercmd.pitch_cmd;
00194 double north_vel_cmd_new = north_cmd_normalized * waypoint_speed;
00195 double east_vel_cmd_new = east_cmd_normalized * waypoint_speed;
00196 double north_cmd_new = north_cmd + north_vel_cmd_new * dt;
00197 double east_cmd_new = east_cmd + east_vel_cmd_new * dt;
00198 if (hover_point_within_bounds(north_cmd_new, east_cmd_new))
00199 {
00200 north_vel_cmd = north_vel_cmd_new;
00201 east_vel_cmd = east_vel_cmd_new;
00202 north_cmd = north_cmd_new;
00203 east_cmd = east_cmd_new;
00204 }
00205 else
00206 {
00207 north_vel_cmd = 0.0;
00208 east_vel_cmd = 0.0;
00209 NODELET_ERROR_THROTTLE(1, "Cannot move hover point out of bounds");
00210 }
00211 }
00212
00213
00214
00215 if (adjusting_yaw)
00216 yaw_cmd = angles::to_degrees(
00217 angles::normalize_angle(
00218 angles::from_degrees(
00219 yaw_cmd + latest_opercmd.yaw_cmd
00220 * max_yaw_rate_cmd * dt)));
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 last_control_output_time = now_time;
00232
00233 HoverMode::outputControl();
00234 }
00235
00236
00237
00238
00239 };
00240 PLUGINLIB_DECLARE_CLASS(flyer_controller, ControlModeHover, flyer_controller::ControlModeHover, nodelet::Nodelet)
00241 ;
00242
00243 }
00244