PageRenderTime 43ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/brown-ros-pkg-read-only/experimental/ardrone_nav/ardrone_lclzr/src/ardrone_lclzr.cpp

https://github.com/dutchcheesehead/ROSMAV
C++ | 606 lines | 362 code | 114 blank | 130 comment | 10 complexity | e2bdab71e4e3827aa7904c7954c48c56 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. This software is meant to localize an ARDrone
  3. */
  4. #include <iostream>
  5. #include <sstream>
  6. #include <ros/ros.h>
  7. #include <tf/transform_broadcaster.h>
  8. #include <std_msgs/String.h>
  9. #include <visualization_msgs/Marker.h>
  10. #include <visualization_msgs/MarkerArray.h>
  11. #include <ardrone_brown/Navdata.h>
  12. #include <ardrone_lclzr/drone_transform.h>
  13. #include "ardrone_state.h"
  14. #include <ar_recog/Tags.h>
  15. #include <ar_recog/Tag.h>
  16. #include "tagserver.h"
  17. #include "ardrone_pf.h"
  18. #include "ardrone_lclzr/ardrone_mean_state.h"
  19. #include "quat_utils.h"
  20. #ifndef PI
  21. #define PI 3.1415926535
  22. #endif
  23. //#define _IMU_VX_MULT_ 0.54
  24. //#define _IMU_VY_MULT_ 0.54
  25. #define _IMU_VX_MULT_ 0.6
  26. #define _IMU_VY_MULT_ 0.6
  27. #define _ARDRONE_STARTX_ 8.21
  28. #define _ARDRONE_STARTY_ 41.885
  29. //#define _ARDRONE_STARTX_ 6.85
  30. //#define _ARDRONE_STARTY_ 43.05
  31. //#define __DEBUG_LEVEL_1
  32. #define __DEBUG_LEVEL_2
  33. double avg_posx;
  34. double avg_posy;
  35. ros::Publisher dronetransform_pub;
  36. //tf::TransformBroadcaster *br;
  37. ros::Publisher particles_visualization;
  38. ros::Publisher avgpos_visualization;
  39. ros::Publisher artag_visualization;
  40. ros::Publisher pub_mean_state;
  41. ardrone_state drone_state;
  42. ardrone_particle_filter ardrone_pfilter;
  43. vector<tagPose> tagposes;
  44. void getSkewSymMatrix(const btVector3& ang_vel, btMatrix3x3& ssmat)
  45. {
  46. ssmat[0][0]=ssmat[1][1]=ssmat[2][2]=0.0;
  47. ssmat[0][1]=-ang_vel[2];
  48. ssmat[1][0]=ang_vel[2];
  49. ssmat[0][2]=ang_vel[1];
  50. ssmat[2][0]=-ang_vel[1];
  51. ssmat[1][2]=-ang_vel[0];
  52. ssmat[2][1]=ang_vel[0];
  53. }
  54. // This gives the XYZ Euler angle rotation matrix as per Craig's book pg 442 Appendix B
  55. // phi is the roll about the body fixed X axis
  56. // theta is the pitch about the body fixed Y axis
  57. // psi is the yaw about the body fixed Z axis
  58. // Input angles are in radians
  59. void getBodyFixedEulerRPYRotationMatrix(double rphi, double rth, double rpsi, btMatrix3x3 &retMat)
  60. {
  61. double xx,xy,xz,yx,yy,yz,zx,zy,zz;
  62. double cphi = cos(rphi);
  63. double cth = cos(rth);
  64. double cpsi = cos(rpsi);
  65. double sphi = sin(rphi);
  66. double sth = sin(rth);
  67. double spsi = sin(rpsi);
  68. double sphisth = sphi*sth;
  69. double cphispsi = cphi*spsi;
  70. double cphicpsi = cphi*cpsi;
  71. xx = cth*cpsi;
  72. xy = -cth*spsi;
  73. xz = sth;
  74. yx = sphisth*cpsi+cphispsi;
  75. yy = -sphisth*spsi+cphicpsi;
  76. yz = -sphi*cth;
  77. zx = -cphicpsi*sth+sphi*spsi;
  78. zy = cphispsi*sth+sphi*cpsi;
  79. zz = cphi*cth;
  80. retMat.setValue(xx, xy, xz, yx, yy, yz, zx, zy, zz);
  81. }
  82. // This returns a yaw(z axis) rotation by rpsi radians
  83. void getYawRotationMatrix(double rpsi, btMatrix3x3 &retMat)
  84. {
  85. double xx,xy,xz,yx,yy,yz,zx,zy,zz;
  86. double cpsi = cos(rpsi);
  87. double spsi = sin(rpsi);
  88. xx = cpsi;
  89. xy = -spsi;
  90. xz = 0.0;
  91. yx = spsi;
  92. yy = cpsi;
  93. yz = 0.0;
  94. zx = 0.0;
  95. zy = 0.0;
  96. zz = 1.0;
  97. retMat.setValue(xx, xy, xz, yx, yy, yz, zx, zy, zz);
  98. }
  99. // This returns a Pitch(Y axis) rotation by rth radians
  100. void getPitchRotationMatrix(double rth, btMatrix3x3 &retMat)
  101. {
  102. double xx,xy,xz,yx,yy,yz,zx,zy,zz;
  103. double cth = cos(rth);
  104. double sth = sin(rth);
  105. xx = cth;
  106. xy = 0.0;
  107. xz = sth;
  108. yx = 0.0;
  109. yy = 1.0;
  110. yz = 0.0;
  111. zx = -sth;
  112. zy = 0.0;
  113. zz = cth;
  114. retMat.setValue(xx, xy, xz, yx, yy, yz, zx, zy, zz);
  115. }
  116. // This returns a Roll(X axis) rotation by rphi radians
  117. void getRollRotationMatrix(double rphi, btMatrix3x3 &retMat)
  118. {
  119. double xx,xy,xz,yx,yy,yz,zx,zy,zz;
  120. double cphi = cos(rphi);
  121. double sphi = sin(rphi);
  122. xx = 1.0;
  123. xy = 0.0;
  124. xz = 0.0;
  125. yx = 0.0;
  126. yy = cphi;
  127. yz = -sphi;
  128. zx = 0.0;
  129. zy = sphi;
  130. zz = cphi;
  131. retMat.setValue(xx, xy, xz, yx, yy, yz, zx, zy, zz);
  132. }
  133. void getYawPitchRollRotationMatrix(double rpsi, double rth, double rphi, btMatrix3x3 &retMat)
  134. {
  135. btMatrix3x3 rpsiRot, rthRot, rphiRot;
  136. getYawRotationMatrix(rpsi, rpsiRot);
  137. getPitchRotationMatrix(rth, rthRot);
  138. getRollRotationMatrix(rphi, rphiRot);
  139. retMat = (rpsiRot*(rthRot*rphiRot));
  140. }
  141. void publish_particles()
  142. {
  143. visualization_msgs::MarkerArray marray;
  144. vector<ardrone_particle>::iterator pf_it = ardrone_pfilter.vec_pf->begin();
  145. int i=0;
  146. btVector3 rotaxis(0,0,1);
  147. btVector3 avg_pos(0,0,0);
  148. btVector3 avg_rpy(0,0,0);
  149. ardrone_lclzr::ardrone_mean_state mean_state;
  150. //this is used to convert from [0,2*PI] or not.
  151. double yaw_correction=0.0;
  152. if((ardrone_pfilter.yaw_min<(PI/2.0))&&(ardrone_pfilter.yaw_max>(3*PI/2.0)))
  153. {
  154. yaw_correction=(-2*PI);
  155. }
  156. for(;pf_it<ardrone_pfilter.vec_pf->end();pf_it++)
  157. {
  158. visualization_msgs::Marker tm;
  159. tm.header.frame_id = "/map";
  160. tm.header.stamp = ros::Time();
  161. tm.ns = "ardrone_particle";
  162. tm.id = i;
  163. tm.type = visualization_msgs::Marker::ARROW;
  164. tm.action = visualization_msgs::Marker::ADD;
  165. tm.pose.position.x = (*pf_it).w_pos[0];
  166. tm.pose.position.y = (*pf_it).w_pos[1];
  167. tm.pose.position.z = 1;
  168. btQuaternion qrot(rotaxis,((*pf_it).drone_rpy[2]));
  169. tm.pose.orientation.x = qrot.x();
  170. tm.pose.orientation.y = qrot.y();
  171. tm.pose.orientation.z = qrot.z();
  172. tm.pose.orientation.w = qrot.w();
  173. tm.scale.x = 1.20;
  174. tm.scale.y = 1.20;
  175. tm.scale.z = 1.20;
  176. tm.color.a = 0.6;
  177. tm.color.r = 0.0;
  178. tm.color.g = 1.0;
  179. tm.color.b = 0.0;
  180. marray.markers.push_back(tm);
  181. avg_pos[0]+=(*pf_it).w_pos[0];
  182. avg_pos[1]+=(*pf_it).w_pos[1];
  183. avg_rpy[2]+=(*pf_it).drone_rpy[2];
  184. if((*pf_it).drone_rpy[2]>(3*PI/2.0))
  185. avg_rpy[2]+=yaw_correction;
  186. i++;
  187. }
  188. //note: avg_rpy[2] is from [0,2*PI]
  189. avg_pos[0]=(avg_pos[0]/i);
  190. avg_pos[1]=(avg_pos[1]/i);
  191. avg_rpy[2]=(avg_rpy[2]/i);
  192. if(avg_rpy[2]<0)
  193. avg_rpy[2]+=(2*PI);
  194. /*
  195. //convert avg_rpy[2] from [0,2*PI] to [-PI,PI]
  196. if(avg_rpy[2]>PI)
  197. {
  198. avg_rpy[2]=(avg_rpy[2]-(2*PI));
  199. }
  200. */
  201. visualization_msgs::Marker avgpos;
  202. avgpos.header.frame_id = "/map";
  203. avgpos.header.stamp = ros::Time();
  204. avgpos.ns = "ardrone_avgpos";
  205. avgpos.id = 0;
  206. avgpos.type = visualization_msgs::Marker::ARROW;
  207. avgpos.action = visualization_msgs::Marker::ADD;
  208. avgpos.pose.position.x = avg_pos[0];
  209. avgpos.pose.position.y = avg_pos[1];
  210. avgpos.pose.position.z = 1;
  211. btQuaternion qrottemp(rotaxis,avg_rpy[2]);
  212. avgpos.pose.orientation.x = qrottemp.x();
  213. avgpos.pose.orientation.y = qrottemp.y();
  214. avgpos.pose.orientation.z = qrottemp.z();
  215. avgpos.pose.orientation.w = qrottemp.w();
  216. avgpos.scale.x = 1.8;
  217. avgpos.scale.y = 1.8;
  218. avgpos.scale.z = 1.8;
  219. avgpos.color.a = 1.0;
  220. avgpos.color.r = 1.0;
  221. avgpos.color.g = 0.0;
  222. avgpos.color.b = 0.0;
  223. double avg_rpy_deg = (avg_rpy[2]/PI*180);
  224. cout << "publish_particles: \n";
  225. cout << "avg_pos[0]: " << avg_pos[0] << "\n";
  226. cout << "avg_pos[1]: " << avg_pos[1] << "\n";
  227. cout << "avg_rpy[2]: " << avg_rpy[2] << "\n";
  228. cout << "avg_rpy_deg[2]: " << avg_rpy_deg << "\n\n";
  229. avg_posx = avg_pos[0];
  230. avg_posy = avg_pos[1];
  231. mean_state.x = avg_pos[0];
  232. mean_state.y = avg_pos[1];
  233. mean_state.thz = avg_rpy[2];
  234. mean_state.vx_droneframe = drone_state.b_lin_vel[0];
  235. mean_state.vy_droneframe = drone_state.b_lin_vel[1];
  236. mean_state.dt = drone_state.dt;
  237. pub_mean_state.publish(mean_state);
  238. particles_visualization.publish(marray);
  239. avgpos_visualization.publish(avgpos);
  240. }
  241. #ifdef __DEBUG_LEVEL_2
  242. btVector3 w_drone_vel;
  243. btVector3 w_drone_pos;
  244. #endif
  245. void navdataCallback(const ardrone_brown::Navdata::ConstPtr& navmsg)
  246. {
  247. std_msgs::String msg;
  248. std::stringstream ss;
  249. if (drone_state.seqcnt==0)
  250. {
  251. drone_state.seqcnt++;
  252. ss << "First update to drone state.\n";
  253. //converting orientation data to radians
  254. double psi = navmsg->rotZ;
  255. double rpsi = psi/180.0*PI;
  256. //change rpsi from [-PI,+PI] to [0,2*PI]
  257. if(rpsi<0)
  258. {
  259. rpsi = (rpsi+2*PI);
  260. }
  261. drone_state.q_yaw.setRPY(0.0,0.0,0.0);
  262. drone_state.q_yaw_prev.setRPY(0.0,0.0,0.0);
  263. drone_state.q_yaw_init.setRPY(0.0,0.0,rpsi);
  264. drone_state.rpsi=0.0;
  265. drone_state.rpsi_prev=0.0;
  266. drone_state.rpsi_init=rpsi;
  267. drone_state.tm=navmsg->tm;
  268. drone_state.dt=0.0;
  269. for(int i=0; i<3; i++)
  270. drone_state.b_lin_vel[i]=0.0;
  271. msg.data=ss.str();
  272. ROS_INFO("%s", msg.data.c_str());
  273. }
  274. else
  275. {
  276. double dt = navmsg->tm - drone_state.tm;
  277. if(dt<0)
  278. {
  279. // navdata message received out of sync, so ignore it
  280. /*
  281. ss << "\n\nnavdata message received with out of sync time stamp.\n";
  282. ss << "dt(usec): " << dt << "\n\n";
  283. msg.data=ss.str();
  284. ROS_INFO("%s", msg.data.c_str());
  285. */
  286. }
  287. else
  288. {
  289. drone_state.seqcnt++;
  290. //convert dt from microseconds to seconds
  291. dt=dt/1000000.0;
  292. drone_state.dt=dt;
  293. drone_state.tm=navmsg->tm;
  294. double psi = navmsg->rotZ;
  295. double rpsi = psi/180.0*PI;
  296. //change rpsi from [-PI,+PI] to [0,2*PI]
  297. if(rpsi<0)
  298. {
  299. rpsi = (rpsi+2*PI);
  300. }
  301. #ifdef __DEBUG_LEVEL_2
  302. btMatrix3x3 w_drone_rotation;
  303. getYawRotationMatrix(rpsi,w_drone_rotation);
  304. btVector3 tdrone_vel(((_IMU_VX_MULT_*navmsg->vx)/1000.0),((_IMU_VX_MULT_*navmsg->vy)/1000.0),(navmsg->vz/1000.0));
  305. btVector3 tw_vel = (w_drone_rotation*tdrone_vel);
  306. btVector3 tw_avg_vel = ((tw_vel+w_drone_vel)/2.0);
  307. btVector3 tw_dr_disp = (dt*tw_avg_vel);
  308. w_drone_pos = (w_drone_pos+tw_dr_disp);
  309. w_drone_vel = tw_vel;
  310. cout << "w_drone_pos: (" << w_drone_pos[0] << "," << w_drone_pos[1]
  311. << "," << w_drone_pos[2] << ")\n";
  312. #endif
  313. drone_state.q_yaw_prev = drone_state.q_yaw;
  314. drone_state.q_yaw.setRPY(0.0,0.0,rpsi);
  315. #ifdef __DEBUG_LEVEL_2
  316. cout << "psi(deg): " << (rpsi/PI*180.0) << "\n";
  317. cout << "1.q_yaw.getAngle(): " << ((drone_state.q_yaw.getAngle())/PI*180.0) << "\n";
  318. #endif
  319. drone_state.q_yaw = getQuaternionDiff(drone_state.q_yaw, drone_state.q_yaw_init);
  320. #ifdef __DEBUG_LEVEL_2
  321. cout << "2.q_yaw.getAngle(): " << ((drone_state.q_yaw.getAngle())/PI*180.0) << "\n";
  322. cout << "q_yaw_init.getAngle(): " << ((drone_state.q_yaw_init.getAngle())/PI*180.0) << "\n";
  323. #endif
  324. drone_state.b_lin_vel[0]=((_IMU_VX_MULT_*navmsg->vx)/1000.0);
  325. drone_state.b_lin_vel[1]=((_IMU_VX_MULT_*navmsg->vy)/1000.0);
  326. drone_state.b_lin_vel[2]=(navmsg->vz/1000.0);
  327. #ifdef __DEBUG_LEVEL_1
  328. ss << "rpsi: " << rpsi << "\n";
  329. ss << "drone_state.q_yaw(rad): "
  330. << getQuaternionAngleRad(drone_state.q_yaw) << "\n";
  331. ss << "drone_state.q_yaw(deg): "
  332. << getQuaternionAngleDeg(drone_state.q_yaw) << "\n";
  333. ss << "drone_state.q_yaw_prev(rad): "
  334. << getQuaternionAngleRad(drone_state.q_yaw_prev) << "\n";
  335. ss << "drone_state.q_yaw_prev(deg): "
  336. << getQuaternionAngleDeg(drone_state.q_yaw_prev) << "\n";
  337. ss << "drone_state.q_yaw_init(rad): "
  338. << getQuaternionAngleRad(drone_state.q_yaw_init) << "\n";
  339. ss << "drone_state.q_yaw_init(deg): "
  340. << getQuaternionAngleDeg(drone_state.q_yaw_init) << "\n";
  341. ss << "\n";
  342. #endif
  343. ardrone_pfilter.perform_motion_update(drone_state);
  344. publish_particles();
  345. #ifdef __DEBUG_LEVEL_1
  346. msg.data=ss.str();
  347. ROS_INFO("%s", msg.data.c_str());
  348. #endif
  349. }
  350. }
  351. }
  352. void tagscallback(const ar_recog::Tags::ConstPtr& tagsmsg)
  353. {
  354. ardrone_pfilter.perform_measurement_update(tagsmsg,tagposes,avg_posx,avg_posy,artag_visualization);
  355. }
  356. int main(int argc, char **argv)
  357. {
  358. ros::init(argc, argv, "ardrone_lclzr");
  359. /*
  360. drone_state.state_initialize(btVector3(0.0,0.0,0.0),btVector3(0.0,0.0,0.0), \
  361. btVector3(0.0,0.0,0.0),btVector3(0.0,0.0,0.0),\
  362. btVector3(0.0,0.0,0.0),btVector3(0.0,0.0,0.0),\
  363. 0.0,0);
  364. */
  365. //br = new tf::TransformBroadcaster();
  366. //drone_state.initialize_pose(btVector3(8.21,41.885,0.0),btVector3(0.0,0.0,0.0));
  367. //drone_state.initialize_pose(btVector3(6.85,43.05,0.0),btVector3(0.0,0.0,0.0));
  368. drone_state.initialize_pose(btVector3(_ARDRONE_STARTX_,_ARDRONE_STARTY_,0.0),btVector3(0.0,0.0,0.0));
  369. //ardrone_pfilter.initialize_particles(btVector3(8.21,41.885,0.0),btVector3(0.0,0.0,0.0));
  370. //ardrone_pfilter.initialize_particles(btVector3(6.85,43.05,0.0),btVector3(0.0,0.0,0.0));
  371. ardrone_pfilter.initialize_particles(btVector3(_ARDRONE_STARTX_,_ARDRONE_STARTY_,0.0),btVector3(0.0,0.0,0.0));
  372. avg_posx=_ARDRONE_STARTX_;
  373. avg_posy=_ARDRONE_STARTY_;
  374. ros::NodeHandle n;
  375. #ifdef __DEBUG_LEVEL_2
  376. w_drone_vel=btVector3(0.0,0.0,0.0);
  377. //w_drone_pos=btVector3(8.21,41.885,0.0);
  378. //w_drone_pos=btVector3(6.85,43.05,0.0);
  379. w_drone_pos=btVector3(_ARDRONE_STARTX_,_ARDRONE_STARTY_,0.0);
  380. #endif
  381. //initialize tagposes
  382. /*
  383. tagPose tag1=tagPose(0,5.85,43.05,-PI/2);
  384. tagposes.push_back(tag1);
  385. //tagPose tag2=tagPose(1,9.21,42.65,-PI/2);
  386. tagPose tag2=tagPose(1,9.21,41.885,-PI/2);
  387. tagposes.push_back(tag2);
  388. */
  389. //tagPose tag1=tagPose(0,9.21,41.885,-PI/2);
  390. tagposes.push_back(tagPose(0,9.21,41.885,-PI/2));
  391. tagposes.push_back(tagPose(0,25.2064,34.461,-PI/2));
  392. tagposes.push_back(tagPose(1,13.33,41.8,-PI/2));
  393. tagposes.push_back(tagPose(1,25.2064,32.461,-PI/2));
  394. tagposes.push_back(tagPose(3,17.8514,41.773,-PI/2));
  395. tagposes.push_back(tagPose(3,25.2064,30.461,-PI/2));
  396. tagposes.push_back(tagPose(4,20.5163,42.0439,-PI/2));
  397. tagposes.push_back(tagPose(4,25.2064,28.461,-PI/2));
  398. tagposes.push_back(tagPose(5,23.1163,42.0439,-PI/2));
  399. tagposes.push_back(tagPose(5,24.8924,27.366,-PI/2));
  400. tagposes.push_back(tagPose(6,24.1163,42.0439,-PI/2));
  401. tagposes.push_back(tagPose(6,24.5795,25.6474,-PI/2));
  402. tagposes.push_back(tagPose(8,25.2063,41.6039,-PI/2));
  403. tagposes.push_back(tagPose(8,23.6941,24.2592,-PI/2));
  404. tagposes.push_back(tagPose(10,25.2064,40.2805,-PI/2));
  405. tagposes.push_back(tagPose(10,21.1235,21.2592,-PI/2));
  406. tagposes.push_back(tagPose(12,25.2064,37.6105,-PI/2));
  407. tagposes.push_back(tagPose(12,18.8635,18.9992,-PI/2));
  408. /*
  409. tagposes.push_back(tagPose(12,25.4464,38.3805,-PI/2));
  410. tagposes.push_back(tagPose(12,18.8635,18.9992,-PI/2));
  411. */
  412. /*
  413. tagPose tag6=tagPose(5,25.1512,41.6566,-PI/2);
  414. tagposes.push_back(tag6);
  415. tagPose tag7=tagPose(6,25.4578,40.5917,-PI/2);
  416. tagposes.push_back(tag7);
  417. tagPose tag8=tagPose(8,25.5224,36.461,-PI/2);
  418. tagposes.push_back(tag8);
  419. tagPose tag9=tagPose(10,25.5708,31.1362,-PI/2);
  420. tagposes.push_back(tag9);
  421. tagPose tag10=tagPose(11,25.5103,28.5868,-PI/2);
  422. tagposes.push_back(tag10);
  423. tagPose tag11=tagPose(12,24.7595,25.6474,-PI/2);
  424. tagposes.push_back(tag11);
  425. */
  426. /*
  427. tagPose tag2=tagPose(0,9.21,41.885,-PI/2);
  428. tagposes.push_back(tag2);
  429. tagPose tag3=tagPose(1,13.33,41.8,-PI/2);
  430. tagposes.push_back(tag3);
  431. tagPose tag4=tagPose(3,17.8514,41.773,-PI/2);
  432. tagposes.push_back(tag4);
  433. tagPose tag5=tagPose(4,20.5163,42.0439,-PI/2);
  434. tagposes.push_back(tag5);
  435. tagPose tag6=tagPose(5,25.1512,41.6566,-PI/2);
  436. tagposes.push_back(tag6);
  437. tagPose tag7=tagPose(6,25.4578,40.5917,-PI/2);
  438. tagposes.push_back(tag7);
  439. tagPose tag8=tagPose(8,25.5224,36.461,-PI/2);
  440. tagposes.push_back(tag8);
  441. tagPose tag9=tagPose(10,25.5708,31.1362,-PI/2);
  442. tagposes.push_back(tag9);
  443. tagPose tag10=tagPose(11,25.5103,28.5868,-PI/2);
  444. tagposes.push_back(tag10);
  445. tagPose tag11=tagPose(12,24.7595,25.6474,-PI/2);
  446. tagposes.push_back(tag11);
  447. */
  448. /*
  449. tagPose tag12=tagPose(11,23.6941,24.2592,-PI/2);
  450. tagposes.push_back(tag12);
  451. tagPose tag13=tagPose(12,21.1235,21.2592,-PI/2);
  452. tagposes.push_back(tag13);
  453. tagPose tag14=tagPose(13,18.8635,18.9992,-PI/2);
  454. tagposes.push_back(tag14);
  455. */
  456. ros::Subscriber navdata_sub = n.subscribe("/ardrone/navdata", 1, &navdataCallback);
  457. //ros::Publisher dronestate_pub = n.advertise<std_msgs::String>("/ardrone_lclzr/dronestate",100);
  458. ros::Subscriber tagsmsg_sub = n.subscribe("tags", 1, &tagscallback);
  459. //particles_pub = n.advertise<ardrone_lclzr::ardrone_pf_particles>("/ardrone/pf_particles",1);
  460. particles_visualization = n.advertise<visualization_msgs::MarkerArray>("visualization_marker_array",1);
  461. avgpos_visualization = n.advertise<visualization_msgs::Marker>("visualization_marker",1);
  462. artag_visualization = n.advertise<visualization_msgs::Marker>("visualization_marker",1);
  463. pub_mean_state = n.advertise<ardrone_lclzr::ardrone_mean_state>("ardrone_mean_state",1);
  464. //dronetransform_pub = n.advertise<ardrone_lclzr::drone_transform>("/ardrone/drone_transform",100);
  465. ros::Rate loop_rate(60);
  466. //int count=0;
  467. while (ros::ok())
  468. {
  469. //dronestate_pub.publish(msg);
  470. ros::spinOnce();
  471. loop_rate.sleep();
  472. //++count;
  473. }
  474. return 0;
  475. }