Go to the documentation of this file.00001
00046 #include "ros/ros.h"
00047 #include "sensor_msgs/NavSatFix.h"
00048 #include "nav_msgs/Odometry.h"
00049
00050 #include <boost/bind.hpp>
00051
00052 extern "C" {
00053
00054 #include "coord_system.h"
00055 }
00056
00057 #define TO_RADIANS (M_PI/180)
00058 #define TO_DEGREES (180/M_PI)
00059
00060 void initialize_datum(double datum_ecef[3],
00061 const sensor_msgs::NavSatFixConstPtr fix_ptr,
00062 const ros::Publisher& pub_datum)
00063 {
00064 ros::NodeHandle n("~");
00065 sensor_msgs::NavSatFix datum_msg(*fix_ptr);
00066
00067
00068
00069
00070
00071
00072 if (n.hasParam("datum_latitude") &&
00073 n.hasParam("datum_longitude") &&
00074 n.hasParam("datum_altitude")) {
00075 n.getParam("datum_latitude", datum_msg.latitude);
00076 n.getParam("datum_longitude", datum_msg.longitude);
00077 n.getParam("datum_altitude", datum_msg.altitude);
00078 ROS_INFO("Using datum provided by node parameters.");
00079 } else {
00080 ROS_INFO("Using initial position fix as datum.");
00081 }
00082 pub_datum.publish(datum_msg);
00083
00084
00085
00086
00087 double llh[3] = { datum_msg.latitude * TO_RADIANS,
00088 datum_msg.longitude * TO_RADIANS,
00089 datum_msg.altitude };
00090 wgsllh2ecef(llh, datum_ecef);
00091 }
00092
00093
00094 static void handle_fix(const sensor_msgs::NavSatFixConstPtr fix_ptr,
00095 const ros::Publisher& pub_enu,
00096 const ros::Publisher& pub_datum)
00097 {
00098 static double ecef_datum[3];
00099 static bool have_datum = false;
00100
00101 if (!have_datum) {
00102 initialize_datum(ecef_datum, fix_ptr, pub_datum);
00103 have_datum = true;
00104 }
00105
00106
00107
00108 double llh[3] = { fix_ptr->latitude * TO_RADIANS,
00109 fix_ptr->longitude * TO_RADIANS,
00110 fix_ptr->altitude };
00111 double ecef[3];
00112 wgsllh2ecef(llh, ecef);
00113
00114
00115
00116 double ned[3];
00117 wgsecef2ned_d(ecef, ecef_datum, ned);
00118
00119 nav_msgs::Odometry odom_msg;
00120 odom_msg.header.stamp = fix_ptr->header.stamp;
00121 odom_msg.pose.pose.position.x = ned[1];
00122 odom_msg.pose.pose.position.y = ned[0];
00123 odom_msg.pose.pose.position.z = -ned[2];
00124
00125
00126
00127
00128 odom_msg.pose.covariance[0] = fix_ptr->position_covariance[0];
00129 odom_msg.pose.covariance[7] = fix_ptr->position_covariance[4];
00130 odom_msg.pose.covariance[14] = fix_ptr->position_covariance[8];
00131
00132
00133 odom_msg.pose.covariance[21] = 1e6;
00134 odom_msg.pose.covariance[28] = 1e6;
00135 odom_msg.pose.covariance[35] = 1e6;
00136
00137
00138 odom_msg.pose.pose.orientation.w = 1;
00139
00140 pub_enu.publish(odom_msg);
00141 }
00142
00143
00144 int main(int argc, char **argv)
00145 {
00146 ros::init(argc, argv, "from_fix");
00147 ros::NodeHandle n;
00148
00149
00150
00151 ros::Publisher pub_enu = n.advertise<nav_msgs::Odometry>("enu", 5);
00152 ros::Publisher pub_datum = n.advertise<sensor_msgs::NavSatFix>("enu_datum", 5, true);
00153 ros::Subscriber sub = n.subscribe<sensor_msgs::NavSatFix>("fix", 5,
00154 boost::bind(handle_fix, _1, pub_enu, pub_datum));
00155
00156 ros::spin();
00157 return 0;
00158 }
00159