00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "flyer_interface/flyer_interface.h"
00023
00024 namespace mav
00025 {
00026
00027 FlyerInterface::FlyerInterface(ros::NodeHandle nh, ros::NodeHandle nh_private):
00028 nh_(nh),
00029 nh_private_(nh_private),
00030 cfg_ctrl_srv_(ros::NodeHandle(nh_private_, "ctrl")),
00031 cfg_x_srv_(ros::NodeHandle(nh_private_, "ctrl/pid_x")),
00032 cfg_y_srv_(ros::NodeHandle(nh_private_, "ctrl/pid_y")),
00033 cfg_z_srv_(ros::NodeHandle(nh_private_, "ctrl/pid_z")),
00034 cfg_vx_srv_(ros::NodeHandle(nh_private_, "ctrl/pid_vx")),
00035 cfg_vy_srv_(ros::NodeHandle(nh_private_, "ctrl/pid_vy")),
00036 cfg_vz_srv_(ros::NodeHandle(nh_private_, "ctrl/pid_vz")),
00037 cfg_yaw_srv_(ros::NodeHandle(nh_private_, "ctrl/pid_yaw")),
00038 cfg_comm_srv_(ros::NodeHandle(nh_private_, "comm")),
00039 connected_(false)
00040 {
00041 ROS_INFO("Starting FlyerInterface");
00042
00043 ros::NodeHandle nh_mav (nh_, "mav");
00044
00045
00046
00047 cmd_roll_ = 0.0;
00048 cmd_pitch_ = 0.0;
00049 cmd_yaw_rate_ = 0.0;
00050 cmd_thrust_ = 0.0;
00051
00052 cpu_load_index_ = 0;
00053
00054 cpu_loads_.resize(50);
00055
00056
00057
00058 initializeParams();
00059
00060
00061
00062 CfgZServer::CallbackType f1 = boost::bind(&FlyerInterface::reconfig_z_callback, this, _1, _2);
00063 cfg_z_srv_.setCallback(f1);
00064
00065 CfgXServer::CallbackType f2 = boost::bind(&FlyerInterface::reconfig_x_callback, this, _1, _2);
00066 cfg_x_srv_.setCallback(f2);
00067
00068 CfgYServer::CallbackType f3 = boost::bind(&FlyerInterface::reconfig_y_callback, this, _1, _2);
00069 cfg_y_srv_.setCallback(f3);
00070
00071 CfgYawServer::CallbackType f4 = boost::bind(&FlyerInterface::reconfig_yaw_callback, this, _1, _2);
00072 cfg_yaw_srv_.setCallback(f4);
00073
00074 CfgCommServer::CallbackType f5 = boost::bind(&FlyerInterface::reconfig_comm_callback, this, _1, _2);
00075 cfg_comm_srv_.setCallback(f5);
00076
00077 CfgCtrlServer::CallbackType f6 = boost::bind(&FlyerInterface::reconfig_ctrl_callback, this, _1, _2);
00078 cfg_ctrl_srv_.setCallback(f6);
00079
00080 CfgVXServer::CallbackType f7 = boost::bind(&FlyerInterface::reconfig_vx_callback, this, _1, _2);
00081 cfg_vx_srv_.setCallback(f7);
00082
00083 CfgVYServer::CallbackType f8 = boost::bind(&FlyerInterface::reconfig_vy_callback, this, _1, _2);
00084 cfg_vy_srv_.setCallback(f8);
00085
00086 CfgVZServer::CallbackType f9 = boost::bind(&FlyerInterface::reconfig_vz_callback, this, _1, _2);
00087 cfg_vz_srv_.setCallback(f9);
00088
00089
00090
00091 connected_ = comm_.connect(serial_port_rx_, serial_port_tx_, baudrate_);
00092
00093 if (!connected_)
00094 {
00095 ROS_ERROR("unable to connect");
00096 return;
00097 }
00098
00099
00100
00101 sendCommConfig();
00102 sendKFConfig(true);
00103 sendPIDConfig();
00104 sendCtrlConfig();
00105
00106
00107
00108 if (publish_pose_)
00109 {
00110 pose_publisher_ = nh_mav.advertise<geometry_msgs::PoseStamped>(
00111 "pose", 10);
00112 }
00113 vel_publisher_ = nh_mav.advertise<geometry_msgs::TwistStamped>(
00114 "vel", 10);
00115 imu_publisher_ = nh_mav.advertise<sensor_msgs::Imu>(
00116 "imu/data", 10);
00117 flight_state_publisher_ = nh_mav.advertise<std_msgs::UInt8>(
00118 "status/flight_state", 1);
00119 battery_voltage_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00120 "status/battery_voltage", 1);
00121 cpu_load_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00122 "status/cpu_load", 1);
00123 cpu_load_avg_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00124 "status/cpu_load_avg", 1);
00125
00126 if (publish_debug_)
00127 {
00128 debug_cmd_roll_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00129 "debug/cmd/roll", 1);
00130 debug_cmd_pitch_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00131 "debug/cmd/pitch", 1);
00132 debug_cmd_yaw_rate_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00133 "debug/cmd/yaw_rate", 1);
00134 debug_cmd_thrust_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00135 "debug/cmd/thrust", 1);
00136
00137 debug_cmd_yaw_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00138 "debug/cmd/yaw", 1);
00139
00140 debug_pid_x_i_term_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00141 "debug/pid/x_i_term", 1);
00142 debug_pid_y_i_term_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00143 "debug/pid/y_i_term", 1);
00144 debug_pid_yaw_i_term_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00145 "debug/pid/yaw_i_term", 1);
00146 debug_pid_z_i_term_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00147 "debug/pid/z_i_term", 1);
00148
00149 debug_roll_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00150 "debug/roll", 1);
00151 debug_pitch_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00152 "debug/pitch", 1);
00153 debug_yaw_publisher_ = nh_mav.advertise<std_msgs::Float32>(
00154 "debug/yaw", 1);
00155
00156 debug_err_x_bf_publisher_= nh_mav.advertise<std_msgs::Float32>(
00157 "debug/pid/err_x_bf", 1);
00158 debug_err_y_bf_publisher_= nh_mav.advertise<std_msgs::Float32>(
00159 "debug/pid/err_y_bf", 1);
00160
00161 debug_err_vx_bf_publisher_= nh_mav.advertise<std_msgs::Float32>(
00162 "debug/pid/err_vx_bf", 1);
00163 debug_err_vy_bf_publisher_= nh_mav.advertise<std_msgs::Float32>(
00164 "debug/pid/err_vy_bf", 1);
00165
00166 debug_ax_bf_publisher_= nh_mav.advertise<std_msgs::Float32>(
00167 "debug/pid/acc_x_bf", 1);
00168 debug_ay_bf_publisher_= nh_mav.advertise<std_msgs::Float32>(
00169 "debug/pid/acc_y_bf", 1);
00170 debug_az_publisher_= nh_mav.advertise<std_msgs::Float32>(
00171 "debug/pid/dvz", 1);
00172
00173 debug_vx_bf_publisher_= nh_mav.advertise<std_msgs::Float32>(
00174 "debug/pid/vx_bf", 1);
00175 debug_vy_bf_publisher_= nh_mav.advertise<std_msgs::Float32>(
00176 "debug/pid/vy_bf", 1);
00177
00178 debug_imu_wf_publisher_ = nh_mav.advertise<sensor_msgs::Imu>(
00179 "debug/imu_wf", 1);
00180 }
00181
00182
00183
00184 comm_.registerCallback(MAV_IMU_PKT_ID, &FlyerInterface::processImuData, this);
00185 comm_.registerCallback(MAV_POSE_PKT_ID, &FlyerInterface::processPoseData, this);
00186 comm_.registerCallback(MAV_RCDATA_PKT_ID, &FlyerInterface::processRCData, this);
00187 comm_.registerCallback(MAV_FLIGHT_STATE_PKT_ID, &FlyerInterface::processFlightStateData, this);
00188 comm_.registerCallback(MAV_TIMESYNC_PKT_ID, &FlyerInterface::processTimeSyncData, this);
00189 comm_.registerCallback(MAV_STATUS_PKT_ID, &FlyerInterface::processStatusData, this);
00190
00191 if (publish_debug_)
00192 comm_.registerCallback(MAV_CTRL_DEBUG_PKT_ID, &FlyerInterface::processCtrlDebugData, this);
00193
00194
00195
00196
00197 int queue_size = 5;
00198
00199 laser_pose_subscriber_.reset(new PoseStampedSubscriber(
00200 nh_mav, "laser_pose_f", queue_size));
00201 laser_vel_subscriber_.reset(new TwistStampedSubscriber(
00202 nh_mav, "laser_vel_f", queue_size));
00203
00204 sync_.reset(new Synchronizer(
00205 SyncPolicy(queue_size), *laser_pose_subscriber_, *laser_vel_subscriber_));
00206 sync_->registerCallback(boost::bind(&FlyerInterface::laserCallback, this, _1, _2));
00207
00208 height_subscriber_ = nh_mav.subscribe(
00209 "laser_height_f", 10, &FlyerInterface::heightCallback, this);
00210
00211 cmd_roll_subscriber_ = nh_mav.subscribe(
00212 "cmd/roll", 10, &FlyerInterface::cmdRollCallback, this);
00213 cmd_pitch_subscriber_ = nh_mav.subscribe(
00214 "cmd/pitch", 10, &FlyerInterface::cmdPitchCallback, this);
00215 cmd_yaw_rate_subscriber_ = nh_mav.subscribe(
00216 "cmd/yaw_rate", 10, &FlyerInterface::cmdYawRateCallback, this);
00217 cmd_thrust_subscriber_ = nh_mav.subscribe(
00218 "cmd/thrust", 10, &FlyerInterface::cmdThrustCallback, this);
00219 cmd_pose_subscriber_ = nh_mav.subscribe(
00220 "cmd/pose", 10, &FlyerInterface::cmdPoseCallback, this);
00221 cmd_vel_subscriber_ = nh_mav.subscribe(
00222 "cmd/vel", 10, &FlyerInterface::cmdVelCallback, this);
00223
00224
00225
00226 cmd_timer_ = nh_private_.createTimer(
00227 ros::Duration(0.05), &FlyerInterface::cmdTimerCallback, this);
00228
00229
00230
00231 advance_state_srv_ = nh_mav.advertiseService(
00232 "advanceState", &FlyerInterface::advanceState, this);
00233 retreat_state_srv_ = nh_mav.advertiseService(
00234 "retreatState", &FlyerInterface::retreatState, this);
00235 estop_srv_ = nh_mav.advertiseService(
00236 "estop", &FlyerInterface::estop, this);
00237
00238 toggle_engage_srv_ = nh_mav.advertiseService(
00239 "toggleEngage", &FlyerInterface::toggleEngage, this);
00240 takeoff_srv_ = nh_mav.advertiseService(
00241 "takeoff", &FlyerInterface::takeoff, this);
00242 land_srv_ = nh_mav.advertiseService(
00243 "land", &FlyerInterface::land, this);
00244
00245 get_flight_state_srv_ = nh_mav.advertiseService(
00246 "getFlightState", &FlyerInterface::getFlightState, this);
00247
00248 set_ctrl_type_srv_ = nh_mav.advertiseService(
00249 "setCtrlType", &FlyerInterface::setCtrlType, this);
00250 }
00251
00252 FlyerInterface::~FlyerInterface()
00253 {
00254 ROS_INFO("Destorying Flyer Interface");
00255 }
00256
00257 void FlyerInterface::initializeParams()
00258 {
00259 if (!nh_private_.getParam ("fixed_frame", fixed_frame_))
00260 fixed_frame_ = "/odom";
00261 if (!nh_private_.getParam ("base_frame", base_frame_))
00262 base_frame_ = "/base_link";
00263 if (!nh_private_.getParam ("publish_pose", publish_pose_))
00264 publish_pose_ = false;
00265 if (!nh_private_.getParam ("publish_debug", publish_debug_))
00266 publish_debug_ = false;
00267
00268
00269
00270 if (!nh_private_.getParam ("comm/serial_port_rx", serial_port_rx_))
00271 serial_port_rx_ = "/dev/ttyUSB0";
00272 if (!nh_private_.getParam ("cogmm/serial_port_tx", serial_port_tx_))
00273 serial_port_tx_ = "/dev/ttyUSB0";
00274 if (!nh_private_.getParam ("comm/baudrate", baudrate_))
00275 baudrate_ = MAV_DEFAULT_BAUDRATE;
00276
00277
00278
00279 if (!nh_private_.getParam ("enable_kf_x", enable_kf_x_))
00280 enable_kf_x_ = "true";
00281 if (!nh_private_.getParam ("enable_kf_y", enable_kf_y_))
00282 enable_kf_y_ = "true";
00283 if (!nh_private_.getParam ("enable_kf_z", enable_kf_z_))
00284 enable_kf_z_ = "true";
00285 if (!nh_private_.getParam ("enable_kf_yaw", enable_kf_yaw_))
00286 enable_kf_yaw_ = "true";
00287
00288 if (!nh_private_.getParam ("q_x", q_x_))
00289 q_x_ = 0.083;
00290 if (!nh_private_.getParam ("q_y", q_y_))
00291 q_y_ = 0.083;
00292 if (!nh_private_.getParam ("q_z", q_z_))
00293 q_z_ = 0.7;
00294 if (!nh_private_.getParam ("q_yaw", q_yaw_))
00295 q_yaw_ = 0.083;
00296
00297 if (!nh_private_.getParam ("r_x", r_x_))
00298 r_x_ = 2.0;
00299 if (!nh_private_.getParam ("r_y", r_y_))
00300 r_y_ = 2.0;
00301 if (!nh_private_.getParam ("r_z", r_z_))
00302 r_z_ = 5.0;
00303 if (!nh_private_.getParam ("r_yaw", r_yaw_))
00304 r_yaw_ = 2.0;
00305
00306 if (!nh_private_.getParam ("r_vx", r_vx_))
00307 r_vx_ = 10.0;
00308 if (!nh_private_.getParam ("r_vy", r_vy_))
00309 r_vy_ = 10.0;
00310 if (!nh_private_.getParam ("r_vz", r_vz_))
00311 r_vz_ = 10.0;
00312 if (!nh_private_.getParam ("r_vz_p", r_vz_p_))
00313 r_vz_p_ = 10.0;
00314
00315
00316
00317 int ctrl_mode_roll, ctrl_mode_pitch, ctrl_mode_yaw_rate, ctrl_mode_thrust;
00318
00319 if (!nh_private_.getParam ("ctrl/ctrl_mode_roll", ctrl_mode_roll))
00320 ctrl_mode_roll = MAV_CTRL_MODE_DIRECT;
00321 if (!nh_private_.getParam ("ctrl/ctrl_mode_pitch", ctrl_mode_pitch))
00322 ctrl_mode_pitch = MAV_CTRL_MODE_DIRECT;
00323 if (!nh_private_.getParam ("ctrl/ctrl_mode_yaw_rate", ctrl_mode_yaw_rate))
00324 ctrl_mode_yaw_rate = MAV_CTRL_MODE_DIRECT;
00325 if (!nh_private_.getParam ("ctrl/ctrl_mode_thrust", ctrl_mode_thrust))
00326 ctrl_mode_thrust = MAV_CTRL_MODE_DIRECT;
00327
00328 ctrl_cfg_packet_.ctrl_mode_roll = ctrl_mode_roll;
00329 ctrl_cfg_packet_.ctrl_mode_pitch = ctrl_mode_pitch;
00330 ctrl_cfg_packet_.ctrl_mode_yaw_rate = ctrl_mode_yaw_rate;
00331 ctrl_cfg_packet_.ctrl_mode_thrust = ctrl_mode_thrust;
00332 }
00333
00334 void FlyerInterface::laserCallback(
00335 const PoseStamped::ConstPtr pose_msg,
00336 const TwistStamped::ConstPtr twist_msg)
00337 {
00338 MAV_POSE2D_PKT packet;
00339
00340 packet.x = pose_msg->pose.position.x;
00341 packet.y = pose_msg->pose.position.y;
00342
00343 packet.vx = twist_msg->twist.linear.x;
00344 packet.vy = twist_msg->twist.linear.y;
00345
00346 packet.yaw = tf::getYaw(pose_msg->pose.orientation);
00347 normalizeSIAngle2Pi(&packet.yaw);
00348
00349 ROS_DEBUG("Sending MAV_POSE2D_PKT packet");
00350 comm_.sendPacket(MAV_POSE2D_PKT_ID, packet);
00351 }
00352
00353 void FlyerInterface::cmdPoseCallback(const geometry_msgs::PoseStamped::ConstPtr cmd_pose_msg)
00354 {
00355
00356 ros::Duration tf_tol(5.0);
00357
00358
00359 std::string frame = tf_listener_.resolve(cmd_pose_msg->header.frame_id);
00360 geometry_msgs::PoseStamped cmd_pose_fixed_frame;
00361
00362 if (frame != fixed_frame_)
00363 {
00364 ROS_INFO_ONCE("cmd_pose messages does not match the fixed frame (%s, %s), transforming",
00365 frame.c_str(), fixed_frame_.c_str());
00366
00367 try
00368 {
00369 tf_listener_.waitForTransform(
00370 fixed_frame_, cmd_pose_msg->header.frame_id, cmd_pose_msg->header.stamp, tf_tol);
00371
00372 tf_listener_.transformPose(fixed_frame_, *cmd_pose_msg, cmd_pose_fixed_frame);
00373 }
00374 catch (tf::TransformException ex)
00375 {
00376 ROS_WARN("Could not transform goal pose %s", ex.what());
00377 return;
00378 }
00379 }
00380 else
00381 {
00382 cmd_pose_fixed_frame = *cmd_pose_msg;
00383 }
00384
00385 MAV_DES_POSE_PKT des_pose_pkt;
00386
00387 des_pose_pkt.x = cmd_pose_fixed_frame.pose.position.x;
00388 des_pose_pkt.y = cmd_pose_fixed_frame.pose.position.y;
00389 des_pose_pkt.z = cmd_pose_fixed_frame.pose.position.z;
00390
00391 float cmd_yaw = tf::getYaw(cmd_pose_fixed_frame.pose.orientation);
00392 normalizeSIAnglePi(&cmd_yaw);
00393
00394 des_pose_pkt.yaw = cmd_yaw;
00395
00396 ROS_DEBUG("Sending MAV_DES_POSE_PKT packet");
00397 comm_.sendPacket(MAV_DES_POSE_PKT_ID, des_pose_pkt);
00398
00399
00400
00401 std_msgs::Float32 cmd_yaw_msg;
00402 cmd_yaw_msg.data = cmd_yaw;
00403 debug_cmd_yaw_publisher_.publish(cmd_yaw_msg);
00404 }
00405
00406 void FlyerInterface::cmdVelCallback(const geometry_msgs::TwistStamped::ConstPtr cmd_vel_msg)
00407 {
00408 MAV_DES_VEL_PKT des_vel_pkt;
00409
00410 des_vel_pkt.vx = cmd_vel_msg->twist.linear.x;
00411 des_vel_pkt.vy = cmd_vel_msg->twist.linear.y;
00412 des_vel_pkt.vz = cmd_vel_msg->twist.linear.z;
00413 des_vel_pkt.yaw_rate = cmd_vel_msg->twist.angular.z;
00414
00415 ROS_DEBUG("Sending MAV_DES_VEL_PKT packet");
00416 comm_.sendPacket(MAV_DES_VEL_PKT_ID, des_vel_pkt);
00417 }
00418
00419 void FlyerInterface::heightCallback(const mav_msgs::Height::ConstPtr height_msg)
00420 {
00421 MAV_HEIGHT_PKT packet;
00422
00423 packet.z = height_msg->height;
00424 packet.vz = height_msg->climb;
00425
00426 ROS_DEBUG("Sending MAV_HEIGHT_PKT packet");
00427 comm_.sendPacket(MAV_HEIGHT_PKT_ID, packet);
00428 }
00429
00430 void FlyerInterface::cmdTimerCallback(const ros::TimerEvent& event)
00431 {
00432 MAV_CTRL_INPUT_PKT ctrl_input_packet;
00433
00434 ctrl_input_packet.cmd_roll = cmd_roll_;
00435 ctrl_input_packet.cmd_pitch = cmd_pitch_;
00436 ctrl_input_packet.cmd_yaw_rate = cmd_yaw_rate_;
00437 ctrl_input_packet.cmd_thrust = cmd_thrust_;
00438
00439 ROS_DEBUG("Sending MAV_CTRL_INPUT_PKT packet");
00440 comm_.sendPacket(MAV_CTRL_INPUT_PKT_ID, ctrl_input_packet);
00441 }
00442
00443 void FlyerInterface::sendKFConfig(bool reset)
00444 {
00445 MAV_KF_CFG_PKT packet;
00446
00447 uint8_t mask = 0x00;
00448
00449 if (enable_kf_x_) mask |= (1 << MAV_KF_X_BIT);
00450 if (enable_kf_y_) mask |= (1 << MAV_KF_Y_BIT);
00451 if (enable_kf_z_) mask |= (1 << MAV_KF_Z_BIT);
00452 if (enable_kf_yaw_) mask |= (1 << MAV_KF_YAW_BIT);
00453
00454 if (reset) mask |= (1 << MAV_KF_RESET_BIT);
00455
00456 packet.enable_mask = mask;
00457
00458 packet.Q_x = q_x_;
00459 packet.Q_y = q_y_;
00460 packet.Q_z = q_z_;
00461 packet.Q_yaw = q_yaw_;
00462
00463 packet.R_x = r_x_;
00464 packet.R_y = r_y_;
00465 packet.R_z = r_z_;
00466 packet.R_yaw = r_yaw_;
00467
00468 packet.R_vx = r_vx_;
00469 packet.R_vy = r_vy_;
00470 packet.R_vz = r_vz_;
00471 packet.R_vz_p = r_vz_p_;
00472
00473 ROS_INFO("Sending MAV_KF_CFG_PKT packet");
00474 comm_.sendPacketAck(MAV_KF_CFG_PKT_ID, packet);
00475 }
00476
00477 void FlyerInterface::sendPIDConfig()
00478 {
00479 ROS_INFO("Sending MAV_PID_CFG_PKT packet");
00480 comm_.sendPacketAck(MAV_PID_CFG_PKT_ID, pid_cfg_packet_);
00481 }
00482
00483 void FlyerInterface::sendCommConfig()
00484 {
00485 ROS_INFO("Sending MAV_TX_FREQ_CFG_PKT packet");
00486 comm_.sendPacketAck(MAV_TX_FREQ_CFG_PKT_ID, tx_freq_cfg_packet_);
00487 }
00488
00489 void FlyerInterface::sendCtrlConfig()
00490 {
00491 ROS_INFO("Sending MAV_CTRL_CFG_PKT packet");
00492 comm_.sendPacketAck(MAV_CTRL_CFG_PKT_ID, ctrl_cfg_packet_);
00493 }
00494
00495 void FlyerInterface::processCtrlDebugData(uint8_t * buf, uint32_t bufLength)
00496 {
00497 ROS_DEBUG("MAV_CTRL_DEBUG_PKT Packet Received");
00498
00499 MAV_CTRL_DEBUG_PKT * ctrl_debug_pkt = (MAV_CTRL_DEBUG_PKT *)buf;
00500
00501
00502
00503 std_msgs::Float32 cmd_roll_msg;
00504 std_msgs::Float32 cmd_pitch_msg;
00505 std_msgs::Float32 cmd_yaw_rate_msg;
00506 std_msgs::Float32 cmd_thrust_msg;
00507
00508 cmd_roll_msg.data = ctrl_debug_pkt->cmd_roll;
00509 cmd_pitch_msg.data = ctrl_debug_pkt->cmd_pitch;
00510 cmd_yaw_rate_msg.data = ctrl_debug_pkt->cmd_yaw_rate;
00511 cmd_thrust_msg.data = ctrl_debug_pkt->cmd_thrust;
00512
00513 debug_cmd_roll_publisher_.publish(cmd_roll_msg);
00514 debug_cmd_pitch_publisher_.publish(cmd_pitch_msg);
00515 debug_cmd_yaw_rate_publisher_.publish(cmd_yaw_rate_msg);
00516 debug_cmd_thrust_publisher_.publish(cmd_thrust_msg);
00517
00518
00519
00520 std_msgs::Float32 pid_x_i_term_msg;
00521 std_msgs::Float32 pid_y_i_term_msg;
00522 std_msgs::Float32 pid_yaw_i_term_msg;
00523 std_msgs::Float32 pid_z_i_term_msg;
00524
00525 pid_x_i_term_msg.data = ctrl_debug_pkt->pid_x_i_term;
00526 pid_y_i_term_msg.data = ctrl_debug_pkt->pid_y_i_term;
00527 pid_yaw_i_term_msg.data = ctrl_debug_pkt->pid_yaw_i_term;
00528 pid_z_i_term_msg.data = ctrl_debug_pkt->pid_z_i_term;
00529
00530 debug_pid_x_i_term_publisher_.publish(pid_x_i_term_msg);
00531 debug_pid_y_i_term_publisher_.publish(pid_y_i_term_msg);
00532 debug_pid_yaw_i_term_publisher_.publish(pid_yaw_i_term_msg);
00533 debug_pid_z_i_term_publisher_.publish(pid_z_i_term_msg);
00534
00535
00536
00537 sensor_msgs::Imu imu_wf;
00538 imu_wf.header.stamp = ros::Time::now();
00539 imu_wf.linear_acceleration.x = ctrl_debug_pkt->acc_x_wf;
00540 imu_wf.linear_acceleration.y = ctrl_debug_pkt->acc_y_wf;
00541 imu_wf.linear_acceleration.z = ctrl_debug_pkt->acc_z_wf;
00542
00543 debug_imu_wf_publisher_.publish(imu_wf);
00544
00545
00546
00547 std_msgs::Float32 err_x_bf_msg;
00548 err_x_bf_msg.data = ctrl_debug_pkt->pid_error_x_bf;
00549 debug_err_x_bf_publisher_.publish(err_x_bf_msg);
00550
00551 std_msgs::Float32 err_y_bf_msg;
00552 err_y_bf_msg.data = ctrl_debug_pkt->pid_error_y_bf;
00553 debug_err_y_bf_publisher_.publish(err_y_bf_msg);
00554
00555
00556
00557 std_msgs::Float32 err_vx_bf_msg;
00558 err_vx_bf_msg.data = ctrl_debug_pkt->pid_error_vx_bf;
00559 debug_err_vx_bf_publisher_.publish(err_vx_bf_msg);
00560
00561 std_msgs::Float32 err_vy_bf_msg;
00562 err_vy_bf_msg.data = ctrl_debug_pkt->pid_error_vy_bf;
00563 debug_err_vy_bf_publisher_.publish(err_vy_bf_msg);
00564
00565
00566
00567 std_msgs::Float32 ax_bf_msg;
00568 ax_bf_msg.data = ctrl_debug_pkt->ax_bf;
00569 debug_ax_bf_publisher_.publish(ax_bf_msg);
00570
00571 std_msgs::Float32 ay_bf_msg;
00572 ay_bf_msg.data = ctrl_debug_pkt->ay_bf;
00573 debug_ay_bf_publisher_.publish(ay_bf_msg);
00574
00575 std_msgs::Float32 az_msg;
00576 az_msg.data = ctrl_debug_pkt->az;
00577 debug_az_publisher_.publish(az_msg);
00578
00579
00580
00581 std_msgs::Float32 vx_bf_msg;
00582 vx_bf_msg.data = ctrl_debug_pkt->vel_x_bf;
00583 debug_vx_bf_publisher_.publish(vx_bf_msg);
00584
00585 std_msgs::Float32 vy_bf_msg;
00586 vy_bf_msg.data = ctrl_debug_pkt->vel_y_bf;
00587 debug_vy_bf_publisher_.publish(vy_bf_msg);
00588
00589
00590
00591 ROS_DEBUG("Ctrl Mode: %d %d %d %d", ctrl_debug_pkt->ctrl_mode_roll,
00592 ctrl_debug_pkt->ctrl_mode_pitch,
00593 ctrl_debug_pkt->ctrl_mode_yaw_rate,
00594 ctrl_debug_pkt->ctrl_mode_thrust);
00595
00596
00597
00598
00599
00600
00601 }
00602
00603 void FlyerInterface::processStatusData(uint8_t * buf, uint32_t bufLength)
00604 {
00605 ROS_DEBUG("MAV_STATUS_PKT Packet Received");
00606
00607 MAV_STATUS_PKT * status_pkt = (MAV_STATUS_PKT *)buf;
00608
00609 std_msgs::Float32 battery_voltage_msg;
00610 battery_voltage_msg.data = status_pkt->battery_voltage / 1000.0;
00611
00612 battery_voltage_publisher_.publish(battery_voltage_msg);
00613
00614 std_msgs::Float32 cpu_load_msg;
00615 cpu_load_msg.data = status_pkt->cpu_load;
00616
00617 cpu_load_publisher_.publish(cpu_load_msg);
00618
00619
00620
00621 cpu_loads_[cpu_load_index_] = (double)status_pkt->cpu_load;
00622 cpu_load_index_++;
00623 if (cpu_load_index_ >= 50) cpu_load_index_ = 0;
00624
00625 double sum = 0.0;
00626 for (int i = 0; i < 50; ++i)
00627 sum += cpu_loads_[i];
00628
00629 double avg = sum / 50.0;
00630
00631 std_msgs::Float32 cpu_load_avg_msg;
00632 cpu_load_avg_msg.data = avg;
00633 cpu_load_avg_publisher_.publish(cpu_load_avg_msg);
00634 }
00635
00636 void FlyerInterface::processPoseData(uint8_t * buf, uint32_t bufLength)
00637 {
00638 ROS_DEBUG("MAV_POSE_PKT Packet Received");
00639 ros::Time time = ros::Time::now();
00640
00641 MAV_POSE_PKT* mav_pose_pkt = (MAV_POSE_PKT*)buf;
00642
00643 if (publish_pose_)
00644 {
00645
00646
00647 geometry_msgs::PoseStamped::Ptr pose_msg;
00648 pose_msg = boost::make_shared<geometry_msgs::PoseStamped>();
00649
00650 pose_msg->header.frame_id = fixed_frame_;
00651 pose_msg->header.stamp = time;
00652
00653 pose_msg->pose.position.x = mav_pose_pkt->x;
00654 pose_msg->pose.position.y = mav_pose_pkt->y;
00655 pose_msg->pose.position.z = mav_pose_pkt->z;
00656
00657 tf::Quaternion q = tf::createQuaternionFromRPY(
00658 mav_pose_pkt->roll, mav_pose_pkt->pitch, mav_pose_pkt->yaw);
00659 tf::quaternionTFToMsg(q, pose_msg->pose.orientation);
00660
00661
00662
00663 pose_publisher_.publish(pose_msg);
00664
00665
00666
00667 tf::Stamped<tf::Pose> f2b;
00668 tf::poseStampedMsgToTF(*pose_msg, f2b);
00669
00670 tf::StampedTransform f2b_tf(f2b, time, fixed_frame_, base_frame_);
00671 tf_broadcaster_.sendTransform(f2b_tf);
00672 }
00673
00674
00675
00676 geometry_msgs::TwistStamped::Ptr twist_msg;
00677 twist_msg = boost::make_shared<geometry_msgs::TwistStamped>();
00678
00679 twist_msg->header.frame_id = fixed_frame_;
00680 twist_msg->header.stamp = time;
00681
00682 twist_msg->twist.linear.x = mav_pose_pkt->vx;
00683 twist_msg->twist.linear.y = mav_pose_pkt->vy;
00684 twist_msg->twist.linear.z = mav_pose_pkt->vz;
00685
00686
00687
00688 vel_publisher_.publish(twist_msg);
00689
00690
00691
00692 std_msgs::Float32 roll_msg, pitch_msg, yaw_msg;
00693
00694 roll_msg.data = mav_pose_pkt->roll;
00695 pitch_msg.data = mav_pose_pkt->pitch;
00696 yaw_msg.data = mav_pose_pkt->yaw;
00697
00698 if (yaw_msg.data > M_PI) yaw_msg.data -= 2.0 * M_PI;
00699 if (yaw_msg.data <= -M_PI) yaw_msg.data += 2.0 * M_PI;
00700
00701 debug_roll_publisher_.publish(roll_msg);
00702 debug_pitch_publisher_.publish(pitch_msg);
00703 debug_yaw_publisher_.publish(yaw_msg);
00704 }
00705
00706 void FlyerInterface::processRCData(uint8_t * buf, uint32_t bufLength)
00707 {
00708
00709 }
00710
00711 void FlyerInterface::processImuData(uint8_t * buf, uint32_t bufLength)
00712 {
00713 ROS_DEBUG("IMU Packet Received");
00714 MAV_IMU_PKT * data = (MAV_IMU_PKT *)buf;
00715
00716
00717
00718 sensor_msgs::Imu::Ptr imu_msg;
00719 imu_msg = boost::make_shared<sensor_msgs::Imu>();
00720
00721 imu_msg->header.frame_id = fixed_frame_;
00722 imu_msg->header.stamp = ros::Time::now();
00723
00724
00725
00726 double roll = data->roll;
00727 double pitch = data->pitch;
00728 double yaw = data->yaw;
00729
00730 tf::Quaternion q = tf::createQuaternionFromRPY(roll, pitch, yaw);
00731 tf::quaternionTFToMsg(q, imu_msg->orientation);
00732
00733
00734
00735 imu_msg->angular_velocity.x = data->roll_rate;
00736 imu_msg->angular_velocity.y = data->pitch_rate;
00737 imu_msg->angular_velocity.z = data->yaw_rate;
00738
00739
00740
00741 imu_msg->linear_acceleration.x = data->acc_x;
00742 imu_msg->linear_acceleration.y = data->acc_y;
00743 imu_msg->linear_acceleration.z = data->acc_z;
00744
00745 imu_publisher_.publish(imu_msg);
00746 }
00747
00748 void FlyerInterface::processFlightStateData(uint8_t * buf, uint32_t bufLength)
00749 {
00750 ROS_DEBUG("MAV_FLIGHT_STATE Packet Received");
00751 MAV_FLIGHT_STATE_PKT * flight_state_pkt = (MAV_FLIGHT_STATE_PKT *)buf;
00752
00753 boost::mutex::scoped_lock lock(state_mutex_);
00754 flight_state_ = flight_state_pkt->state;
00755
00756
00757 std_msgs::UInt8 flight_state_msg;
00758 flight_state_msg.data = flight_state_;
00759
00760 flight_state_publisher_.publish(flight_state_msg);
00761 }
00762
00763 bool FlyerInterface::advanceState(mav_srvs::AdvanceState::Request &req,
00764 mav_srvs::AdvanceState::Response &res)
00765 {
00766 MAV_FLIGHT_ACTION_PKT packet;
00767
00768 packet.action = MAV_ACTION_ADVANCE_STATE;
00769
00770 ROS_INFO("Sending MAV_ACTION_PKT: Advance State");
00771 return comm_.sendPacket(MAV_FLIGHT_ACTION_PKT_ID, packet);
00772 }
00773
00774 bool FlyerInterface::retreatState(mav_srvs::AdvanceState::Request &req,
00775 mav_srvs::AdvanceState::Response &res)
00776 {
00777 MAV_FLIGHT_ACTION_PKT packet;
00778
00779 packet.action = MAV_ACTION_RETREAT_STATE;
00780
00781 ROS_INFO("Sending MAV_ACTION_PKT: Retreat State");
00782 return comm_.sendPacket(MAV_FLIGHT_ACTION_PKT_ID, packet);
00783 }
00784
00785 bool FlyerInterface::estop(mav_srvs::ESTOP::Request &req,
00786 mav_srvs::ESTOP::Response &res)
00787 {
00788 MAV_FLIGHT_ACTION_PKT packet;
00789
00790 packet.action = MAV_ACTION_ESTOP;
00791
00792 ROS_WARN("Sending MAV_ACTION_PKT: ESTOP");
00793 return comm_.sendPacket(MAV_FLIGHT_ACTION_PKT_ID, packet);
00794 }
00795
00796 bool FlyerInterface::getFlightState(mav_srvs::GetFlightState::Request &req,
00797 mav_srvs::GetFlightState::Response &res)
00798 {
00799 boost::mutex::scoped_lock lock(state_mutex_);
00800 res.state = flight_state_;
00801
00802 return true;
00803 }
00804
00805 bool FlyerInterface::setCtrlType(mav_srvs::SetCtrlType::Request &req,
00806 mav_srvs::SetCtrlType::Response &res)
00807 {
00808 if (req.ctrl_type == mav::PositionCtrl)
00809 {
00810 ROS_INFO("Ctrl type changed to POSITION:");
00811
00812 ctrl_cfg_packet_.ctrl_mode_roll = MAV_CTRL_MODE_POSITION;
00813 ctrl_cfg_packet_.ctrl_mode_pitch = MAV_CTRL_MODE_POSITION;
00814 ctrl_cfg_packet_.ctrl_mode_yaw_rate = MAV_CTRL_MODE_POSITION;
00815 ctrl_cfg_packet_.ctrl_mode_thrust = MAV_CTRL_MODE_POSITION;
00816 }
00817 else if (req.ctrl_type == mav::VelocityCtrl)
00818 {
00819 ROS_INFO("Ctrl type changed to VELOCITY:");
00820
00821 ctrl_cfg_packet_.ctrl_mode_roll = MAV_CTRL_MODE_VELOCITY;
00822 ctrl_cfg_packet_.ctrl_mode_pitch = MAV_CTRL_MODE_VELOCITY;
00823 ctrl_cfg_packet_.ctrl_mode_yaw_rate = MAV_CTRL_MODE_VELOCITY;
00824 ctrl_cfg_packet_.ctrl_mode_thrust = MAV_CTRL_MODE_POSITION;
00825 }
00826 else
00827 {
00828 ROS_WARN("Unknown ctrl mode requested");
00829 return false;
00830 }
00831
00832 ROS_INFO("\tRoll: %d", ctrl_cfg_packet_.ctrl_mode_roll);
00833 ROS_INFO("\tPitch: %d", ctrl_cfg_packet_.ctrl_mode_pitch);
00834 ROS_INFO("\tYaw rate: %d", ctrl_cfg_packet_.ctrl_mode_yaw_rate);
00835 ROS_INFO("\tThrust: %d", ctrl_cfg_packet_.ctrl_mode_thrust);
00836
00837 if (connected_) sendCtrlConfig();
00838
00839 return true;
00840 }
00841
00842 bool FlyerInterface::toggleEngage(mav_srvs::ToggleEngage::Request &req,
00843 mav_srvs::ToggleEngage::Response &res)
00844 {
00845 MAV_FLIGHT_ACTION_PKT packet;
00846
00847 packet.action = MAV_ACTION_TOGGLE_ENGAGE;
00848
00849 ROS_INFO("Sending MAV_ACTION_PKT: Toggle engage");
00850 return comm_.sendPacket(MAV_FLIGHT_ACTION_PKT_ID, packet);
00851 }
00852
00853 bool FlyerInterface::land(mav_srvs::Land::Request &req,
00854 mav_srvs::Land::Response &res)
00855 {
00856 MAV_FLIGHT_ACTION_PKT packet;
00857
00858 packet.action = MAV_ACTION_LAND;
00859
00860 ROS_INFO("Sending MAV_ACTION_PKT: Land");
00861 return comm_.sendPacket(MAV_FLIGHT_ACTION_PKT_ID, packet);
00862 }
00863
00864 bool FlyerInterface::takeoff(mav_srvs::Takeoff::Request &req,
00865 mav_srvs::Takeoff::Response &res)
00866 {
00867 MAV_FLIGHT_ACTION_PKT packet;
00868
00869 packet.action = MAV_ACTION_TAKEOFF;
00870
00871 ROS_INFO("Sending MAV_ACTION_PKT: Takeoff");
00872 return comm_.sendPacket(MAV_FLIGHT_ACTION_PKT_ID, packet);
00873 }
00874
00875 void FlyerInterface::processTimeSyncData(uint8_t * buf, uint32_t bufLength)
00876 {
00877 ROS_INFO("MAV_TIMESYNC_PKT received");
00878
00879 static bool synced_once = false;
00880 MAV_TIMESYNC_PKT data = *(MAV_TIMESYNC_PKT*)buf;
00881
00882 if (!synced_once)
00883 {
00884 data.ts1 = 1e12;
00885 synced_once = true;
00886 ROS_INFO("Forced sync");
00887 }
00888 else
00889 {
00890 data.ts1 = (uint64_t)(ros::Time::now().toSec() * 1.0e6);
00891 ROS_INFO("Synced");
00892 }
00893
00894 comm_.sendPacket(MAV_TIMESYNC_PKT_ID, data);
00895
00896
00897
00898 }
00899
00900 void FlyerInterface::cmdRollCallback(const mav_msgs::Roll::ConstPtr roll_msg)
00901 {
00902 cmd_roll_ = roll_msg->roll;
00903 }
00904
00905 void FlyerInterface::cmdPitchCallback(const mav_msgs::Pitch::ConstPtr pitch_msg)
00906 {
00907 cmd_pitch_ = pitch_msg->pitch;
00908 }
00909
00910 void FlyerInterface::cmdYawRateCallback(const mav_msgs::YawRate::ConstPtr yaw_rate_msg)
00911 {
00912 cmd_yaw_rate_ = yaw_rate_msg->yaw_rate;
00913 }
00914
00915 void FlyerInterface::cmdThrustCallback(const mav_msgs::Thrust::ConstPtr thrust_msg)
00916 {
00917 cmd_thrust_ = thrust_msg->thrust;
00918 }
00919
00920 void FlyerInterface::reconfig_x_callback(PIDXConfig& config, uint32_t level)
00921 {
00922 pid_cfg_packet_.k_p_x = config.k_p;
00923 pid_cfg_packet_.k_i_x = config.k_i;
00924 pid_cfg_packet_.k_d_x = config.k_d;
00925 pid_cfg_packet_.k_d2_x = config.k_d2;
00926 pid_cfg_packet_.d_base_x = config.d_base;
00927 pid_cfg_packet_.bias_x = config.bias;
00928 pid_cfg_packet_.max_i_x = config.max_i;
00929 pid_cfg_packet_.max_err_x = config.max_err;
00930
00931 if (connected_) sendPIDConfig();
00932 }
00933
00934 void FlyerInterface::reconfig_y_callback(PIDYConfig& config, uint32_t level)
00935 {
00936 pid_cfg_packet_.k_p_y = config.k_p;
00937 pid_cfg_packet_.k_i_y = config.k_i;
00938 pid_cfg_packet_.k_d_y = config.k_d;
00939 pid_cfg_packet_.k_d2_y = config.k_d2;
00940 pid_cfg_packet_.d_base_y = config.d_base;
00941 pid_cfg_packet_.bias_y = config.bias;
00942 pid_cfg_packet_.max_i_y = config.max_i;
00943 pid_cfg_packet_.max_err_y = config.max_err;
00944
00945 if (connected_) sendPIDConfig();
00946 }
00947
00948 void FlyerInterface::reconfig_z_callback(PIDZConfig& config, uint32_t level)
00949 {
00950 pid_cfg_packet_.k_p_z = config.k_p;
00951 pid_cfg_packet_.k_i_z = config.k_i;
00952 pid_cfg_packet_.k_d_z = config.k_d;
00953 pid_cfg_packet_.bias_z = config.bias;
00954 pid_cfg_packet_.max_i_z = config.max_i;
00955 pid_cfg_packet_.max_err_z = config.max_err;
00956
00957 if (connected_) sendPIDConfig();
00958 }
00959
00960 void FlyerInterface::reconfig_vx_callback(PIDVXConfig& config, uint32_t level)
00961 {
00962 pid_cfg_packet_.k_p_vx = config.k_p;
00963 pid_cfg_packet_.k_i_vx = config.k_i;
00964 pid_cfg_packet_.k_d_vx = config.k_d;
00965 pid_cfg_packet_.bias_vx = config.bias;
00966 pid_cfg_packet_.max_i_vx = config.max_i;
00967 pid_cfg_packet_.max_err_vx = config.max_err;
00968
00969 if (connected_) sendPIDConfig();
00970 }
00971
00972 void FlyerInterface::reconfig_vy_callback(PIDVYConfig& config, uint32_t level)
00973 {
00974 pid_cfg_packet_.k_p_vy = config.k_p;
00975 pid_cfg_packet_.k_i_vy = config.k_i;
00976 pid_cfg_packet_.k_d_vy = config.k_d;
00977 pid_cfg_packet_.bias_vy = config.bias;
00978 pid_cfg_packet_.max_i_vy = config.max_i;
00979 pid_cfg_packet_.max_err_vy = config.max_err;
00980
00981 if (connected_) sendPIDConfig();
00982 }
00983
00984 void FlyerInterface::reconfig_vz_callback(PIDVZConfig& config, uint32_t level)
00985 {
00986 pid_cfg_packet_.k_p_vz = config.k_p;
00987 pid_cfg_packet_.k_i_vz = config.k_i;
00988 pid_cfg_packet_.k_d_vz = config.k_d;
00989 pid_cfg_packet_.bias_vz = config.bias;
00990 pid_cfg_packet_.max_i_vz = config.max_i;
00991 pid_cfg_packet_.max_err_vz = config.max_err;
00992
00993 if (connected_) sendPIDConfig();
00994 }
00995
00996
00997 void FlyerInterface::reconfig_yaw_callback(PIDYawConfig& config, uint32_t level)
00998 {
00999 pid_cfg_packet_.k_p_yaw = config.k_p;
01000 pid_cfg_packet_.k_i_yaw = config.k_i;
01001 pid_cfg_packet_.k_d_yaw = config.k_d;
01002 pid_cfg_packet_.bias_yaw = config.bias;
01003 pid_cfg_packet_.max_i_yaw = config.max_i;
01004 pid_cfg_packet_.max_err_yaw = config.max_err;
01005
01006 if (connected_) sendPIDConfig();
01007 }
01008
01009 void FlyerInterface::reconfig_ctrl_callback(CtrlConfig& config, uint32_t level)
01010 {
01011 ctrl_cfg_packet_.cmd_roll_limit = config.cmd_roll_limit;
01012 ctrl_cfg_packet_.cmd_pitch_limit = config.cmd_pitch_limit;
01013 ctrl_cfg_packet_.cmd_yaw_rate_limit = config.cmd_yaw_rate_limit;
01014 ctrl_cfg_packet_.cmd_thrust_limit = config.cmd_thrust_limit;
01015
01016 ctrl_cfg_packet_.cmd_roll_delta_limit = config.cmd_roll_delta_limit;
01017 ctrl_cfg_packet_.cmd_pitch_delta_limit = config.cmd_pitch_delta_limit;
01018 ctrl_cfg_packet_.cmd_yaw_rate_delta_limit = config.cmd_yaw_rate_delta_limit;
01019 ctrl_cfg_packet_.cmd_thrust_delta_limit = config.cmd_thrust_delta_limit;
01020
01021 if (connected_) sendCtrlConfig();
01022 }
01023
01024 void FlyerInterface::reconfig_comm_callback(CommConfig& config, uint32_t level)
01025 {
01026 tx_freq_cfg_packet_.imu_period = config.imu_period;
01027 tx_freq_cfg_packet_.imu_phase = config.imu_phase;
01028
01029 tx_freq_cfg_packet_.pose_period = config.pose_period;
01030 tx_freq_cfg_packet_.pose_phase = config.pose_phase;
01031
01032 tx_freq_cfg_packet_.rcdata_period = config.rcdata_period;
01033 tx_freq_cfg_packet_.rcdata_phase = config.rcdata_phase;
01034
01035 tx_freq_cfg_packet_.flight_state_period = config.flight_state_period;
01036 tx_freq_cfg_packet_.flight_state_phase = config.flight_state_phase;
01037
01038 tx_freq_cfg_packet_.status_period = config.status_period;
01039 tx_freq_cfg_packet_.status_phase = config.status_phase;
01040
01041 tx_freq_cfg_packet_.ctrl_debug_period = config.debug_period;
01042 tx_freq_cfg_packet_.ctrl_debug_phase = config.debug_phase;
01043
01044 if (connected_) sendCommConfig();
01045 }
01046
01047 }