Go to the documentation of this file.00001
00037 #include <boost/bind.hpp>
00038 #include <string>
00039
00040 #include "ros/ros.h"
00041 #include "sensor_msgs/NavSatFix.h"
00042 #include "nav_msgs/Odometry.h"
00043 #include "enu/ToENU.h"
00044 #include "enu/enu.h"
00045
00046
00047 void initialize_datum(const sensor_msgs::NavSatFix& fix,
00048 const ros::Publisher& pub_datum,
00049 sensor_msgs::NavSatFix* datum_ptr) {
00050 ros::NodeHandle pnh("~");
00051
00052
00053
00054
00055
00056
00057 if (pnh.hasParam("datum_latitude") &&
00058 pnh.hasParam("datum_longitude") &&
00059 pnh.hasParam("datum_altitude")) {
00060 pnh.getParam("datum_latitude", datum_ptr->latitude);
00061 pnh.getParam("datum_longitude", datum_ptr->longitude);
00062 pnh.getParam("datum_altitude", datum_ptr->altitude);
00063 ROS_INFO("Using datum provided by node parameters.");
00064 } else {
00065 datum_ptr->latitude = fix.latitude;
00066 datum_ptr->longitude = fix.longitude;
00067 datum_ptr->altitude = fix.altitude;
00068 ROS_INFO("Using initial position fix as datum.");
00069 }
00070 pub_datum.publish(*datum_ptr);
00071 }
00072
00073
00074 static void handle_fix(const sensor_msgs::NavSatFixConstPtr fix_ptr,
00075 const ros::Publisher& pub_odom,
00076 const ros::Publisher& pub_datum,
00077 const std::string& output_tf_frame,
00078 const double invalid_covariance_value,
00079 const double scale_covariance,
00080 const double lock_altitude) {
00081 static sensor_msgs::NavSatFix datum;
00082 static bool have_datum = false;
00083
00084 if (!have_datum) {
00085 initialize_datum(*fix_ptr, pub_datum, &datum);
00086 have_datum = true;
00087 }
00088
00089
00090
00091 nav_msgs::Odometry odom;
00092 enu::fix_to_point(*fix_ptr, datum, &odom.pose.pose.position);
00093 if (lock_altitude!=-1)
00094 odom.pose.pose.position.z = lock_altitude;
00095
00096 odom.header.stamp = fix_ptr->header.stamp;
00097 odom.header.frame_id = output_tf_frame;
00098 odom.child_frame_id = fix_ptr->header.frame_id;
00099
00100
00101 odom.pose.pose.orientation.x = 0;
00102 odom.pose.pose.orientation.y = 0;
00103 odom.pose.pose.orientation.z = 0;
00104 odom.pose.pose.orientation.w = 1;
00105
00106
00107
00108
00109 odom.pose.covariance[0] = fix_ptr->position_covariance[0]*scale_covariance;
00110 odom.pose.covariance[7] = fix_ptr->position_covariance[4]*scale_covariance;
00111 odom.pose.covariance[14] = fix_ptr->position_covariance[8]*scale_covariance;
00112
00113
00114
00115 odom.pose.covariance[21] = invalid_covariance_value;
00116 odom.pose.covariance[28] = invalid_covariance_value;
00117 odom.pose.covariance[35] = invalid_covariance_value;
00118
00119 pub_odom.publish(odom);
00120 }
00121
00122 bool toENUService(const enu::ToENU::Request& req, enu::ToENU::Response& resp) {
00123 enu::fix_to_point(req.llh, req.datum, &(resp.enu));
00124 return true;
00125 }
00126
00127 int main(int argc, char **argv) {
00128 ros::init(argc, argv, "from_fix");
00129 ros::NodeHandle n;
00130 ros::NodeHandle pnh("~");
00131
00132 std::string output_tf_frame;
00133 pnh.param<std::string>("output_frame_id", output_tf_frame, "map");
00134 double invalid_covariance_value;
00135 double scale_covariance;
00136 double lock_altitude;
00137 pnh.param<double>("invalid_covariance_value", invalid_covariance_value, -1.0);
00138 pnh.param<double>("scale_covariance", scale_covariance,1.0);
00139 pnh.param<double>("lock_altitude", lock_altitude, -1.0);
00140
00141
00142
00143 ros::Publisher pub_odom = n.advertise<nav_msgs::Odometry>("enu", 5);
00144 ros::Publisher pub_datum = n.advertise<sensor_msgs::NavSatFix>("enu_datum", 5, true);
00145 ros::Subscriber sub = n.subscribe<sensor_msgs::NavSatFix>("fix", 5,
00146 boost::bind(handle_fix, _1, pub_odom, pub_datum, output_tf_frame, invalid_covariance_value,scale_covariance, lock_altitude));
00147 ros::ServiceServer srv = n.advertiseService<enu::ToENU::Request, enu::ToENU::Response> ("ToENU", toENUService);
00148
00149 ros::spin();
00150 return 0;
00151 }
00152