00001
00025 #include <signal.h>
00026 #include <string>
00027 #include <algorithm>
00028 #include <vector>
00029
00030 #include <ardrone_autonomy/ardrone_driver.h>
00031 #include <ardrone_autonomy/teleop_twist.h>
00032 #include <ardrone_autonomy/video.h>
00033
00034
00036
00038
00039 ARDroneDriver::ARDroneDriver()
00040 : private_nh("~"),
00041 image_transport(node_handle),
00042
00043 initialized_navdata_publishers(false),
00044 last_frame_id(-1),
00045 last_navdata_id(-1),
00046 is_inited(false),
00047 last_receive_time(0.0)
00048 {
00049 cmd_vel_sub = node_handle.subscribe("cmd_vel", 1, &CmdVelCallback);
00050 takeoff_sub = node_handle.subscribe("ardrone/takeoff", 1, &TakeoffCallback);
00051 reset_sub = node_handle.subscribe("ardrone/reset", 1, &ResetCallback);
00052 land_sub = node_handle.subscribe("ardrone/land", 1, &LandCallback);
00053 image_pub = image_transport.advertiseCamera("ardrone/image_raw", 10);
00054 hori_pub = image_transport.advertiseCamera("ardrone/front/image_raw", 10);
00055 vert_pub = image_transport.advertiseCamera("ardrone/bottom/image_raw", 10);
00056 toggle_cam_srv = node_handle.advertiseService("ardrone/togglecam", ToggleCamCallback);
00057 set_cam_channel_srv = node_handle.advertiseService("ardrone/setcamchannel", SetCamChannelCallback);
00058 set_led_animation_srv = node_handle.advertiseService("ardrone/setledanimation", SetLedAnimationCallback);
00059 flat_trim_srv = node_handle.advertiseService("ardrone/flattrim", FlatTrimCallback);
00060 set_flight_anim_srv = node_handle.advertiseService("ardrone/setflightanimation", SetFlightAnimationCallback);
00061 set_record_srv = node_handle.advertiseService("ardrone/setrecord", SetRecordCallback);
00062
00063
00064 private_nh.param<std::string>("drone_frame_id", drone_frame_id, "ardrone_base");
00065 drone_frame_base = drone_frame_id + "_link";
00066 drone_frame_imu = drone_frame_id + "_imu";
00067 drone_frame_front_cam = drone_frame_id + "_frontcam";
00068 drone_frame_bottom_cam = drone_frame_id + "_bottomcam";
00069
00070 if (private_nh.hasParam("root_frame"))
00071 {
00072 ROS_WARN("Changing `root_frame` has been deprecated since version 1.4. ");
00073 }
00074
00075
00076
00077 for (int i = 0; i < 9; i++)
00078 {
00079 imu_msg.linear_acceleration_covariance[i] = 0.0;
00080 imu_msg.angular_velocity_covariance[i] = 0.0;
00081 imu_msg.orientation_covariance[i] = 0.0;
00082 }
00083 ReadCovParams("~cov/imu_la", imu_msg.linear_acceleration_covariance);
00084 ReadCovParams("~cov/imu_av", imu_msg.angular_velocity_covariance);
00085 ReadCovParams("~cov/imu_or", imu_msg.orientation_covariance);
00086
00087 if (private_nh.hasParam("do_imu_caliberation"))
00088 {
00089 ROS_WARN("IMU Caliberation has been deprecated since 1.4.");
00090 }
00091
00092
00093 cinfo_hori = new camera_info_manager::CameraInfoManager(ros::NodeHandle("ardrone/front"), "ardrone_front");
00094 cinfo_vert = new camera_info_manager::CameraInfoManager(ros::NodeHandle("ardrone/bottom"), "ardrone_bottom");
00095
00096
00097
00098
00099
00100
00101 tf_base_front = tf::StampedTransform(
00102 tf::Transform(
00103 tf::createQuaternionFromRPY(-90.0 * _DEG2RAD, 0.0, -90.0 * _DEG2RAD),
00104 tf::Vector3(0.21, 0.0, 0.0)),
00105 ros::Time::now(), drone_frame_base, drone_frame_front_cam);
00106
00107
00108
00109 tf_base_bottom = tf::StampedTransform(
00110 tf::Transform(
00111 tf::createQuaternionFromRPY(180.0 * _DEG2RAD, 0.0, 90.0 * _DEG2RAD),
00112 tf::Vector3(0.0, -0.02, 0.0)),
00113 ros::Time::now(), drone_frame_base, drone_frame_bottom_cam);
00114
00115
00116 odometry[0] = odometry[1] = 0;
00117 }
00118
00119 ARDroneDriver::~ARDroneDriver()
00120 {
00121 delete cinfo_hori;
00122 delete cinfo_vert;
00123 }
00124
00125 void ARDroneDriver::run()
00126 {
00127 ros::Rate loop_rate(looprate);
00128 const ros::Time startTime = ros::Time::now();
00129 static int freq_dev = 0;
00130 while (node_handle.ok())
00131 {
00132 if (!is_inited)
00133 {
00134 if (((ros::Time::now() - startTime).toSec()) > 5.0)
00135 {
00136 is_inited = true;
00137
00138
00139 ConfigureDrone();
00140
00141 vp_os_mutex_lock(&navdata_lock);
00142 ROS_INFO("Successfully connected to '%s' (AR-Drone %d.0 - Firmware: %s) - Battery(%%): %d",
00143 ardrone_control_config.ardrone_name,
00144 (IS_ARDRONE1) ? 1 : 2,
00145 ardrone_control_config.num_version_soft,
00146 shared_raw_navdata_ptr->navdata_demo.vbat_flying_percentage);
00147 ROS_INFO("Navdata Publish Settings:");
00148 ROS_INFO(" Legacy Navdata Mode: %s", enabled_legacy_navdata ? "On" : "Off");
00149 ROS_INFO(" ROS Loop Rate: %d Hz", looprate);
00150 ROS_INFO(" Realtime Navdata Publish: %s", realtime_navdata ? "On" : "Off");
00151 ROS_INFO(" Realtime Video Publish: %s", realtime_video ? "On" : "Off");
00152 ROS_INFO(" Drone Navdata Send Speed: %s",
00153 ardrone_application_default_config.navdata_demo == 0 ?
00154 "200Hz (navdata_demo=0)" : "15Hz (navdata_demo=1)");
00155
00156 vp_os_mutex_unlock(&navdata_lock);
00157 if (ardrone_control_config.num_version_soft[0] == '0')
00158 {
00159 ROS_WARN("The AR-Drone has a suspicious Firmware number. It usually means the network link is unreliable.");
00160 }
00161 }
00162 }
00163 else
00164 {
00165 if (!realtime_video)
00166 {
00167 vp_os_mutex_lock(&video_lock);
00168 copy_current_frame_id = current_frame_id;
00169 vp_os_mutex_unlock(&video_lock);
00170 if (copy_current_frame_id != last_frame_id)
00171 {
00172 last_frame_id = copy_current_frame_id;
00173 PublishVideo();
00174 }
00175 }
00176
00177 if (!realtime_navdata)
00178 {
00179 vp_os_mutex_lock(&navdata_lock);
00180 copy_current_navdata_id = current_navdata_id;
00181 vp_os_mutex_unlock(&navdata_lock);
00182 if (copy_current_navdata_id != last_navdata_id)
00183 {
00184 vp_os_mutex_lock(&navdata_lock);
00185 last_navdata_id = copy_current_navdata_id;
00186
00187
00188
00189
00190 const navdata_unpacked_t navdata_raw = *shared_raw_navdata_ptr;
00191 const ros::Time navdata_receive_time = shared_navdata_receive_time;
00192 vp_os_mutex_unlock(&navdata_lock);
00193
00194
00195 PublishNavdataTypes(navdata_raw, navdata_receive_time);
00196 PublishNavdata(navdata_raw, navdata_receive_time);
00197 PublishOdometry(navdata_raw, navdata_receive_time);
00198 }
00199 }
00200 if (freq_dev == 0) PublishTF();
00201
00202
00203
00204 freq_dev = (freq_dev + 1) % 5;
00205 }
00206 ros::spinOnce();
00207 loop_rate.sleep();
00208 }
00209 printf("ROS loop terminated ... \n");
00210 }
00211
00212 void ARDroneDriver::ConfigureDrone()
00213 {
00214 #include "ardrone_autonomy/snippet_configure_drone.h"
00215 }
00216
00217 double ARDroneDriver::CalcAverage(const std::vector<double> &vec)
00218 {
00219 double ret = 0.0;
00220 for (unsigned int i = 0; i < vec.size(); i++)
00221 {
00222 ret += vec[i];
00223 }
00224 return (ret / vec.size());
00225 }
00226
00227 bool ARDroneDriver::ReadCovParams(const std::string ¶m_name, boost::array<double, 9> &cov_array)
00228 {
00229 XmlRpc::XmlRpcValue cov_list;
00230 std::stringstream str_stream;
00231 if (ros::param::get(param_name, cov_list))
00232 {
00233 if (cov_list.getType() != XmlRpc::XmlRpcValue::TypeArray)
00234 {
00235 ROS_WARN("Covariance values for %s is not a list", param_name.c_str());
00236 return false;
00237 }
00238
00239 if (cov_list.size() != 9)
00240 {
00241 ROS_WARN("Covariance list size for %s is not of size 9 (Size: %d)", param_name.c_str(), cov_list.size());
00242 return false;
00243 }
00244 str_stream << param_name << " set to [";
00245 for (int32_t i = 0; i < cov_list.size(); i++)
00246 {
00247 ROS_ASSERT(cov_list[i].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00248 cov_array[i] = static_cast<double>(cov_list[i]);
00249 str_stream << cov_array[i] << ((i < 8) ? ", " : "");
00250 }
00251 str_stream << "]";
00252 ROS_INFO("%s", str_stream.str().c_str());
00253 return true;
00254 }
00255 else
00256 {
00257 ROS_INFO("No values found for `%s` in parameters, set all to zero.", param_name.c_str());
00258 return false;
00259 }
00260 }
00261
00262 void ARDroneDriver::PublishVideo()
00263 {
00264 if (
00265 (image_pub.getNumSubscribers() == 0) &&
00266 (hori_pub.getNumSubscribers() == 0) &&
00267 (vert_pub.getNumSubscribers() == 0)
00268 ) return;
00269
00270
00271
00272 sensor_msgs::CameraInfo cinfo_msg_hori = cinfo_hori->getCameraInfo();
00273 sensor_msgs::CameraInfo cinfo_msg_vert = cinfo_vert->getCameraInfo();
00274
00275 cinfo_msg_hori.header.frame_id = drone_frame_front_cam;
00276 cinfo_msg_vert.header.frame_id = drone_frame_bottom_cam;
00277
00278 if (IS_ARDRONE1)
00279 {
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 sensor_msgs::Image image_msg;
00299 sensor_msgs::Image::_data_type::iterator _it;
00300
00301 if ((cam_state == ZAP_CHANNEL_HORI) || (cam_state == ZAP_CHANNEL_LARGE_HORI_SMALL_VERT))
00302 {
00303 image_msg.header.frame_id = drone_frame_front_cam;
00304 }
00305 else if ((cam_state == ZAP_CHANNEL_VERT) || (cam_state == ZAP_CHANNEL_LARGE_VERT_SMALL_HORI))
00306 {
00307 image_msg.header.frame_id = drone_frame_bottom_cam;
00308 }
00309 else
00310 {
00311 ROS_WARN_ONCE("Something is wrong with camera channel config.");
00312 }
00313
00314 image_msg.width = D1_STREAM_WIDTH;
00315 image_msg.height = D1_STREAM_HEIGHT;
00316 image_msg.encoding = "rgb8";
00317 image_msg.is_bigendian = false;
00318 image_msg.step = D1_STREAM_WIDTH * 3;
00319 image_msg.data.resize(D1_STREAM_WIDTH * D1_STREAM_HEIGHT * 3);
00320
00321 if (!realtime_video) vp_os_mutex_lock(&video_lock);
00322 image_msg.header.stamp = shared_video_receive_time;
00323 std::copy(buffer, buffer + (D1_STREAM_WIDTH * D1_STREAM_HEIGHT * 3), image_msg.data.begin());
00324 if (!realtime_video) vp_os_mutex_unlock(&video_lock);
00325
00326 cinfo_msg_hori.header.stamp = image_msg.header.stamp;
00327 cinfo_msg_vert.header.stamp = image_msg.header.stamp;
00328
00329 if (cam_state == ZAP_CHANNEL_HORI)
00330 {
00331
00332
00333
00334 cinfo_msg_hori.width = D1_STREAM_WIDTH;
00335 cinfo_msg_hori.height = D1_STREAM_HEIGHT;
00336
00337 image_pub.publish(image_msg, cinfo_msg_hori);
00338 hori_pub.publish(image_msg, cinfo_msg_hori);
00339 }
00340 else if (cam_state == ZAP_CHANNEL_VERT)
00341 {
00342
00343
00344
00345 image_msg.width = D1_VERTSTREAM_WIDTH;
00346 image_msg.height = D1_VERTSTREAM_HEIGHT;
00347 image_msg.encoding = "rgb8";
00348 image_msg.is_bigendian = false;
00349 image_msg.step = D1_VERTSTREAM_WIDTH * 3;
00350 image_msg.data.clear();
00351 image_msg.data.resize(D1_VERTSTREAM_WIDTH * D1_VERTSTREAM_HEIGHT * 3);
00352 _it = image_msg.data.begin();
00353 if (!realtime_video) vp_os_mutex_lock(&video_lock);
00354 for (int row = 0; row < D1_VERTSTREAM_HEIGHT ; row++)
00355 {
00356 int _b = row * D1_STREAM_WIDTH * 3;
00357 int _e = _b + image_msg.step;
00358 _it = std::copy(buffer + _b, buffer + _e, _it);
00359 }
00360 if (!realtime_video) vp_os_mutex_unlock(&video_lock);
00361
00362 cinfo_msg_vert.width = D1_VERTSTREAM_WIDTH;
00363 cinfo_msg_vert.height = D1_VERTSTREAM_HEIGHT;
00364 image_pub.publish(image_msg, cinfo_msg_vert);
00365 vert_pub.publish(image_msg, cinfo_msg_vert);
00366 }
00367 else if (cam_state == ZAP_CHANNEL_LARGE_HORI_SMALL_VERT)
00368 {
00369
00370
00371
00372
00373
00374
00375 image_msg.width = D1_STREAM_WIDTH - D1_MODE2_PIP_WIDTH;
00376 image_msg.height = D1_STREAM_HEIGHT;
00377 image_msg.encoding = "rgb8";
00378 image_msg.is_bigendian = false;
00379 image_msg.step = (D1_STREAM_WIDTH - D1_MODE2_PIP_WIDTH) * 3;
00380 image_msg.data.clear();
00381 image_msg.data.resize((D1_STREAM_WIDTH - D1_MODE2_PIP_WIDTH)*D1_STREAM_HEIGHT * 3);
00382 _it = image_msg.data.begin();
00383 if (!realtime_video) vp_os_mutex_lock(&video_lock);
00384 for (int row = 0; row < D1_STREAM_HEIGHT; row++)
00385 {
00386 int _b = (row * D1_STREAM_WIDTH * 3) + (D1_MODE2_PIP_WIDTH * 3);
00387 int _e = _b + image_msg.step;
00388 _it = std::copy(buffer + _b, buffer + _e, _it);
00389 }
00390 if (!realtime_video) vp_os_mutex_unlock(&video_lock);
00391
00392 cinfo_msg_hori.width = D1_STREAM_WIDTH - D1_MODE2_PIP_WIDTH;
00393 cinfo_msg_hori.height = D1_STREAM_HEIGHT;
00394 hori_pub.publish(image_msg, cinfo_msg_hori);
00395
00396
00397 image_msg.width = D1_MODE2_PIP_WIDTH;
00398 image_msg.height = D1_MODE2_PIP_HEIGHT;
00399 image_msg.encoding = "rgb8";
00400 image_msg.is_bigendian = false;
00401 image_msg.step = D1_MODE2_PIP_WIDTH * 3;
00402 image_msg.data.clear();
00403 image_msg.data.resize(D1_MODE2_PIP_WIDTH * D1_MODE2_PIP_HEIGHT * 3);
00404 _it = image_msg.data.begin();
00405 if (!realtime_video) vp_os_mutex_lock(&video_lock);
00406 for (int row = 0; row < D1_MODE2_PIP_HEIGHT; row++)
00407 {
00408 int _b = row * D1_STREAM_WIDTH * 3;
00409 int _e = _b + image_msg.step;
00410 _it = std::copy(buffer + _b, buffer + _e, _it);
00411 }
00412 if (!realtime_video) vp_os_mutex_unlock(&video_lock);
00413
00414 cinfo_msg_vert.width = D1_MODE2_PIP_WIDTH;
00415 cinfo_msg_vert.height = D1_MODE2_PIP_HEIGHT;
00416 vert_pub.publish(image_msg, cinfo_msg_vert);
00417 }
00418 else if (cam_state == ZAP_CHANNEL_LARGE_VERT_SMALL_HORI)
00419 {
00420
00421
00422
00423
00424
00425
00426 image_msg.width = D1_VERTSTREAM_WIDTH - D1_MODE3_PIP_WIDTH;
00427 image_msg.height = D1_VERTSTREAM_HEIGHT;
00428 image_msg.encoding = "rgb8";
00429 image_msg.is_bigendian = false;
00430 image_msg.step = (D1_VERTSTREAM_WIDTH - D1_MODE3_PIP_WIDTH) * 3;
00431 image_msg.data.clear();
00432 image_msg.data.resize((D1_VERTSTREAM_WIDTH - D1_MODE3_PIP_WIDTH)* D1_VERTSTREAM_HEIGHT * 3);
00433 _it = image_msg.data.begin();
00434 for (int row = 0; row < D1_VERTSTREAM_HEIGHT; row++)
00435 {
00436 int _b = (row * (D1_STREAM_WIDTH * 3)) + (D1_MODE3_PIP_WIDTH * 3);
00437 int _e = _b + image_msg.step;
00438 if (!realtime_video) vp_os_mutex_lock(&video_lock);
00439 _it = std::copy(buffer + _b, buffer + _e, _it);
00440 if (!realtime_video) vp_os_mutex_unlock(&video_lock);
00441 }
00442
00443 cinfo_msg_vert.width = D1_VERTSTREAM_WIDTH - D1_MODE3_PIP_WIDTH;
00444 cinfo_msg_vert.height = D1_VERTSTREAM_HEIGHT;
00445 vert_pub.publish(image_msg, cinfo_msg_vert);
00446
00447
00448 image_msg.width = D1_MODE3_PIP_WIDTH;
00449 image_msg.height = D1_MODE3_PIP_HEIGHT;
00450 image_msg.encoding = "rgb8";
00451 image_msg.is_bigendian = false;
00452 image_msg.step = D1_MODE3_PIP_WIDTH * 3;
00453 image_msg.data.clear();
00454 image_msg.data.resize(D1_MODE3_PIP_WIDTH * D1_MODE3_PIP_HEIGHT * 3);
00455 _it = image_msg.data.begin();
00456 if (!realtime_video) vp_os_mutex_lock(&video_lock);
00457 for (int row = 0; row < D1_MODE3_PIP_HEIGHT; row++)
00458 {
00459 int _b = row * D1_STREAM_WIDTH * 3;
00460 int _e = _b + image_msg.step;
00461 _it = std::copy(buffer + _b, buffer + _e, _it);
00462 }
00463 if (!realtime_video) vp_os_mutex_unlock(&video_lock);
00464
00465 cinfo_msg_hori.width = D1_MODE3_PIP_WIDTH;
00466 cinfo_msg_hori.height = D1_MODE3_PIP_HEIGHT;
00467 hori_pub.publish(image_msg, cinfo_msg_hori);
00468 }
00469 }
00470
00476 if (IS_ARDRONE2)
00477 {
00478 sensor_msgs::Image image_msg;
00479 sensor_msgs::Image::_data_type::iterator _it;
00480
00481 if (cam_state == ZAP_CHANNEL_HORI)
00482 {
00483 image_msg.header.frame_id = drone_frame_front_cam;
00484 }
00485 else if (cam_state == ZAP_CHANNEL_VERT)
00486 {
00487 image_msg.header.frame_id = drone_frame_bottom_cam;
00488 }
00489 else
00490 {
00491 ROS_WARN_ONCE("Something is wrong with camera channel config.");
00492 }
00493
00494 image_msg.width = D2_STREAM_WIDTH;
00495 image_msg.height = D2_STREAM_HEIGHT;
00496 image_msg.encoding = "rgb8";
00497 image_msg.is_bigendian = false;
00498 image_msg.step = D2_STREAM_WIDTH * 3;
00499 image_msg.data.resize(D2_STREAM_WIDTH * D2_STREAM_HEIGHT * 3);
00500 if (!realtime_video) vp_os_mutex_lock(&video_lock);
00501 image_msg.header.stamp = shared_video_receive_time;
00502 std::copy(buffer, buffer + (D2_STREAM_WIDTH * D2_STREAM_HEIGHT * 3), image_msg.data.begin());
00503 if (!realtime_video) vp_os_mutex_unlock(&video_lock);
00504
00505
00506 cinfo_msg_hori.header.stamp = image_msg.header.stamp;
00507 cinfo_msg_vert.header.stamp = image_msg.header.stamp;
00508
00509 if (cam_state == ZAP_CHANNEL_HORI)
00510 {
00511
00512
00513
00514 cinfo_msg_hori.width = D2_STREAM_WIDTH;
00515 cinfo_msg_hori.height = D2_STREAM_HEIGHT;
00516 image_pub.publish(image_msg, cinfo_msg_hori);
00517 hori_pub.publish(image_msg, cinfo_msg_hori);
00518 }
00519 else if (cam_state == ZAP_CHANNEL_VERT)
00520 {
00521
00522
00523
00524 cinfo_msg_vert.width = D2_STREAM_WIDTH;
00525 cinfo_msg_vert.height = D2_STREAM_HEIGHT;
00526 image_pub.publish(image_msg, cinfo_msg_vert);
00527 vert_pub.publish(image_msg, cinfo_msg_vert);
00528 }
00529 }
00530 }
00531
00532 void ARDroneDriver::PublishNavdata(const navdata_unpacked_t &navdata_raw, const ros::Time &navdata_receive_time)
00533 {
00534 if (!enabled_legacy_navdata ||
00535 ((navdata_pub.getNumSubscribers() == 0) &&
00536 (imu_pub.getNumSubscribers() == 0) &&
00537 (mag_pub.getNumSubscribers() == 0)))
00538 return;
00539
00540 legacynavdata_msg.header.stamp = navdata_receive_time;
00541 legacynavdata_msg.header.frame_id = drone_frame_base;
00542 legacynavdata_msg.batteryPercent = navdata_raw.navdata_demo.vbat_flying_percentage;
00543 legacynavdata_msg.state = (navdata_raw.navdata_demo.ctrl_state >> 16);
00544
00545
00546 legacynavdata_msg.rotX = navdata_raw.navdata_demo.phi / 1000.0;
00547 legacynavdata_msg.rotY = -navdata_raw.navdata_demo.theta / 1000.0;
00548 legacynavdata_msg.rotZ = -navdata_raw.navdata_demo.psi / 1000.0;
00549
00550 legacynavdata_msg.altd = navdata_raw.navdata_demo.altitude;
00551 legacynavdata_msg.vx = navdata_raw.navdata_demo.vx;
00552 legacynavdata_msg.vy = -navdata_raw.navdata_demo.vy;
00553 legacynavdata_msg.vz = -navdata_raw.navdata_demo.vz;
00554
00555
00556 legacynavdata_msg.tm = (navdata_raw.navdata_time.time & 0x001FFFFF) + (navdata_raw.navdata_time.time >> 21) * 1000000;
00557 legacynavdata_msg.ax = navdata_raw.navdata_phys_measures.phys_accs[ACC_X] / 1000.0;
00558 legacynavdata_msg.ay = -navdata_raw.navdata_phys_measures.phys_accs[ACC_Y] / 1000.0;
00559 legacynavdata_msg.az = -navdata_raw.navdata_phys_measures.phys_accs[ACC_Z] / 1000.0;
00560
00561 legacynavdata_msg.motor1 = navdata_raw.navdata_pwm.motor1;
00562 legacynavdata_msg.motor2 = navdata_raw.navdata_pwm.motor2;
00563 legacynavdata_msg.motor3 = navdata_raw.navdata_pwm.motor3;
00564 legacynavdata_msg.motor4 = navdata_raw.navdata_pwm.motor4;
00565
00566
00567
00568 if (IS_ARDRONE2)
00569 {
00570 legacynavdata_msg.magX = (int32_t)navdata_raw.navdata_magneto.mx;
00571 legacynavdata_msg.magY = (int32_t)navdata_raw.navdata_magneto.my;
00572 legacynavdata_msg.magZ = (int32_t)navdata_raw.navdata_magneto.mz;
00573
00574 legacynavdata_msg.pressure = navdata_raw.navdata_pressure_raw.Pression_meas;
00575 legacynavdata_msg.temp = navdata_raw.navdata_pressure_raw.Temperature_meas;
00576
00577 legacynavdata_msg.wind_speed = navdata_raw.navdata_wind_speed.wind_speed;
00578 legacynavdata_msg.wind_angle = navdata_raw.navdata_wind_speed.wind_angle;
00579 legacynavdata_msg.wind_comp_angle = navdata_raw.navdata_wind_speed.wind_compensation_phi;
00580 }
00581 else
00582 {
00583 legacynavdata_msg.magX = legacynavdata_msg.magY = legacynavdata_msg.magZ = 0;
00584 legacynavdata_msg.pressure = 0.0;
00585 legacynavdata_msg.temp = 0.0;
00586 legacynavdata_msg.wind_speed = 0.0;
00587 legacynavdata_msg.wind_angle = 0.0;
00588 legacynavdata_msg.wind_comp_angle = 0.0;
00589 }
00590
00591
00592 legacynavdata_msg.tags_type.clear();
00593 legacynavdata_msg.tags_xc.clear();
00594 legacynavdata_msg.tags_yc.clear();
00595 legacynavdata_msg.tags_width.clear();
00596 legacynavdata_msg.tags_height.clear();
00597 legacynavdata_msg.tags_orientation.clear();
00598 legacynavdata_msg.tags_distance.clear();
00599
00600 legacynavdata_msg.tags_count = navdata_raw.navdata_vision_detect.nb_detected;
00601 for (int i = 0; i < navdata_raw.navdata_vision_detect.nb_detected; i++)
00602 {
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 legacynavdata_msg.tags_type.push_back(navdata_raw.navdata_vision_detect.type[i]);
00615 legacynavdata_msg.tags_xc.push_back(navdata_raw.navdata_vision_detect.xc[i]);
00616 legacynavdata_msg.tags_yc.push_back(navdata_raw.navdata_vision_detect.yc[i]);
00617 legacynavdata_msg.tags_width.push_back(navdata_raw.navdata_vision_detect.width[i]);
00618 legacynavdata_msg.tags_height.push_back(navdata_raw.navdata_vision_detect.height[i]);
00619 legacynavdata_msg.tags_orientation.push_back(navdata_raw.navdata_vision_detect.orientation_angle[i]);
00620 legacynavdata_msg.tags_distance.push_back(navdata_raw.navdata_vision_detect.dist[i]);
00621 }
00622
00623
00624 imu_msg.header.frame_id = drone_frame_base;
00625 imu_msg.header.stamp = navdata_receive_time;
00626
00627
00628 imu_msg.linear_acceleration.x = legacynavdata_msg.ax * 9.8;
00629 imu_msg.linear_acceleration.y = legacynavdata_msg.ay * 9.8;
00630 imu_msg.linear_acceleration.z = legacynavdata_msg.az * 9.8;
00631
00632
00633 tf::Quaternion q;
00634 q.setRPY(legacynavdata_msg.rotX * _DEG2RAD, legacynavdata_msg.rotY * _DEG2RAD, legacynavdata_msg.rotZ * _DEG2RAD);
00635 tf::quaternionTFToMsg(q, imu_msg.orientation);
00636
00637
00638
00639 imu_msg.angular_velocity.x = navdata_raw.navdata_phys_measures.phys_gyros[GYRO_X] * DEG_TO_RAD;
00640 imu_msg.angular_velocity.y = -navdata_raw.navdata_phys_measures.phys_gyros[GYRO_Y] * DEG_TO_RAD;
00641 imu_msg.angular_velocity.z = -navdata_raw.navdata_phys_measures.phys_gyros[GYRO_Z] * DEG_TO_RAD;
00642
00643 mag_msg.header.frame_id = drone_frame_base;
00644 mag_msg.header.stamp = navdata_receive_time;
00645 const float mag_normalizer = sqrt(legacynavdata_msg.magX * legacynavdata_msg.magX +
00646 legacynavdata_msg.magY * legacynavdata_msg.magY +
00647 legacynavdata_msg.magZ * legacynavdata_msg.magZ);
00648
00649
00650 if (fabs(mag_normalizer) > 1e-9f)
00651 {
00652 mag_msg.vector.x = legacynavdata_msg.magX / mag_normalizer;
00653 mag_msg.vector.y = legacynavdata_msg.magY / mag_normalizer;
00654 mag_msg.vector.z = legacynavdata_msg.magZ / mag_normalizer;
00655 mag_pub.publish(mag_msg);
00656 }
00657 else
00658 {
00659 ROS_WARN_THROTTLE(30, "There is something wrong with the magnetometer readings (Magnitude is extremely small).");
00660 }
00661
00662 navdata_pub.publish(legacynavdata_msg);
00663 imu_pub.publish(imu_msg);
00664 }
00665
00666
00667 #define NAVDATA_STRUCTS_SOURCE
00668 #include <ardrone_autonomy/NavdataMessageDefinitions.h>
00669 #undef NAVDATA_STRUCTS_SOURCE
00670
00671 void ARDroneDriver::PublishTF()
00672 {
00673 tf_base_front.stamp_ = ros::Time::now();
00674 tf_base_bottom.stamp_ = ros::Time::now();
00675 tf_odom.stamp_ = ros::Time::now();
00676 tf_broad.sendTransform(tf_base_front);
00677 tf_broad.sendTransform(tf_base_bottom);
00678 tf_broad.sendTransform(tf_odom);
00679 }
00680
00681 void ARDroneDriver::PublishOdometry(const navdata_unpacked_t &navdata_raw, const ros::Time &navdata_receive_time)
00682 {
00683 if (last_receive_time.isValid())
00684 {
00685 double delta_t = (navdata_receive_time - last_receive_time).toSec();
00686 odometry[0] += ((cos((navdata_raw.navdata_demo.psi / 180000.0) * M_PI) *
00687 navdata_raw.navdata_demo.vx - sin((navdata_raw.navdata_demo.psi / 180000.0) * M_PI) *
00688 -navdata_raw.navdata_demo.vy) * delta_t) / 1000.0;
00689 odometry[1] += ((sin((navdata_raw.navdata_demo.psi / 180000.0) * M_PI) *
00690 navdata_raw.navdata_demo.vx + cos((navdata_raw.navdata_demo.psi / 180000.0) * M_PI) *
00691 -navdata_raw.navdata_demo.vy) * delta_t) / 1000.0;
00692 }
00693 last_receive_time = navdata_receive_time;
00694
00695 nav_msgs::Odometry odo_msg;
00696 odo_msg.header.stamp = navdata_receive_time;
00697 odo_msg.header.frame_id = "odom";
00698 odo_msg.child_frame_id = drone_frame_base;
00699
00700 odo_msg.pose.pose.position.x = odometry[0];
00701 odo_msg.pose.pose.position.y = odometry[1];
00702 odo_msg.pose.pose.position.z = navdata_raw.navdata_demo.altitude / 1000;
00703 odo_msg.pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(
00704 navdata_raw.navdata_demo.phi / 180000.0 * M_PI,
00705 -navdata_raw.navdata_demo.theta / 180000.0 * M_PI,
00706 -navdata_raw.navdata_demo.psi / 180000.0 * M_PI);
00707
00708 odo_msg.twist.twist.linear.x = navdata_raw.navdata_demo.vx / 1000.0;
00709 odo_msg.twist.twist.linear.y = -navdata_raw.navdata_demo.vy / 1000.0;
00710 odo_msg.twist.twist.linear.z = -navdata_raw.navdata_demo.vz / 1000.0;
00711
00712 if (odo_pub.getNumSubscribers() > 0)
00713 {
00714 odo_pub.publish(odo_msg);
00715 }
00716
00717 tf::Vector3 t;
00718 tf::pointMsgToTF(odo_msg.pose.pose.position, t);
00719 tf::Quaternion q;
00720 tf::quaternionMsgToTF(odo_msg.pose.pose.orientation, q);
00721
00722 tf_odom.frame_id_ = "odom";
00723 tf_odom.child_frame_id_ = drone_frame_base;
00724 tf_odom.setOrigin(t);
00725 tf_odom.setRotation(q);
00726 }
00727
00728 void ControlCHandler(int signal)
00729 {
00730 ros::shutdown();
00731 should_exit = 1;
00732 }
00733
00735
00737
00738
00739 int main(int argc, char** argv)
00740 {
00741 C_RESULT res = C_FAIL;
00742 char * drone_ip_address = NULL;
00743
00744
00745
00746
00747 ros::init(argc, argv, "ardrone_driver", ros::init_options::NoSigintHandler);
00748
00749 signal(SIGABRT, &ControlCHandler);
00750 signal(SIGTERM, &ControlCHandler);
00751 signal(SIGINT, &ControlCHandler);
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 argc--;
00763 argv++;
00764 while (argc && *argv[0] == '-')
00765 {
00766 if (!strcmp(*argv, "-ip") && (argc > 1))
00767 {
00768 drone_ip_address = *(argv + 1);
00769 printf("Using custom ip address %s\n", drone_ip_address);
00770 argc--;
00771 argv++;
00772 }
00773 argc--;
00774 argv++;
00775 }
00776
00777
00778 vp_com_wifi_config_t *config = reinterpret_cast<vp_com_wifi_config_t*>(wifi_config());
00779
00780 if (config)
00781 {
00782 vp_os_memset(&wifi_ardrone_ip[0], 0, ARDRONE_IPADDRESS_SIZE);
00783
00784
00785 if (drone_ip_address)
00786 {
00787 printf("===================+> %s\n", drone_ip_address);
00788 strncpy(&wifi_ardrone_ip[0], drone_ip_address, ARDRONE_IPADDRESS_SIZE - 1);
00789 }
00790 else
00791 {
00792 printf("===================+> %s\n", config->server);
00793 strncpy(&wifi_ardrone_ip[0], config->server, ARDRONE_IPADDRESS_SIZE - 1);
00794 }
00795 }
00796
00797 while (-1 == getDroneVersion(".", wifi_ardrone_ip, &ardroneVersion))
00798 {
00799 printf("Getting AR.Drone version ...\n");
00800 vp_os_delay(250);
00801 }
00802
00803
00804 res = ardrone_tool_setup_com(NULL);
00805 if (FAILED(res))
00806 {
00807 PRINT("Wifi initialization failed. It means either:\n");
00808 PRINT("\t* you're not root (it's mandatory because you can set up wifi connection only as root)\n");
00809 PRINT("\t* wifi device is not present (on your pc or on your card)\n");
00810 PRINT("\t* you set the wrong name for wifi interface (for example rausb0 instead of wlan0) \n");
00811 PRINT("\t* ap is not up (reboot card or remove wifi usb dongle)\n");
00812 PRINT("\t* wifi device has no antenna\n");
00813 }
00814 else
00815 {
00816
00817 const char* appname = reinterpret_cast<const char*>(DRIVER_APPNAME);
00818 const char* usrname = reinterpret_cast<const char*>(DRIVER_USERNAME);
00819 ardrone_gen_appid(appname, "2.0", app_id, app_name, APPLI_NAME_SIZE);
00820 ardrone_gen_usrid(usrname, usr_id, usr_name, USER_NAME_SIZE);
00821
00822
00823
00824
00825 res = ardrone_tool_init(wifi_ardrone_ip,
00826 strlen(wifi_ardrone_ip),
00827 NULL,
00828 app_name,
00829 usr_name,
00830 NULL,
00831 NULL,
00832 MAX_FLIGHT_STORING_SIZE,
00833 NULL);
00834
00835 while (SUCCEED(res) && ardrone_tool_exit() == FALSE)
00836 {
00837 res = ardrone_tool_update();
00838 }
00839 res = ardrone_tool_shutdown();
00840 }
00841 return SUCCEED(res) ? 0 : -1;
00842 }