00001 #include "hector_elevation_visualization.h"
00002
00003
00004
00005 #define MAP_IDX(sx, i, j) ((sx) * (j) + (i))
00006
00007
00008 ElevationVisualization::ElevationVisualization(): nHandle("~")
00009 {
00010 nHandle.param("max_height_levels",max_height_levels,10);
00011 nHandle.param("min_height",min_height,-1.0);
00012 nHandle.param("max_height",max_height,1.5);
00013 nHandle.param("color_factor",color_factor,0.8);
00014 double r, g, b, a;
00015 nHandle.param("color/r", r, 0.0);
00016 nHandle.param("color/g", g, 0.0);
00017 nHandle.param("color/b", b, 1.0);
00018 nHandle.param("color/a", a, 1.0);
00019 marker_color.r = r;
00020 marker_color.g = g;
00021 marker_color.b = b;
00022 marker_color.a = a;
00023 nHandle.param("use_color_map", use_color_map, true);
00024
00025 nHandle.param("elevation_map_frame_id", elevation_map_frame_id,std::string("/elevation_map_local"));
00026 nHandle.param("paramSysMsgTopic", sys_msg_topic, std::string("/syscommand"));
00027
00028 map_marker_array_publisher = nHandle.advertise<visualization_msgs::MarkerArray>("elevation_map_marker_array", 1,true);
00029
00030 sub_elevation_map = nHandle.subscribe(elevation_map_frame_id,1,&ElevationVisualization::map_callback,this);
00031 sub_sys_message_callback = nHandle.subscribe(sys_msg_topic,1,&ElevationVisualization::sys_message_callback,this);
00032
00033 dyn_rec_server_.setCallback(boost::bind(&ElevationVisualization::dynRecParamCallback, this, _1, _2));
00034
00035 ros::spin();
00036 }
00037
00038 ElevationVisualization::~ElevationVisualization()
00039 {
00040
00041 }
00042
00043 void ElevationVisualization::dynRecParamCallback(hector_elevation_visualization::ElevationVisualizationConfig &config, uint32_t level)
00044 {
00045 max_height_levels = config.max_height_levels;
00046 min_height = config.min_height;
00047 max_height = config.max_height;
00048 color_factor = config.color_factor;
00049 use_color_map = config.use_color_map;
00050
00051 if(std::strcmp(elevation_map_frame_id.c_str(),(config.elevation_map_frame_id).c_str()))
00052 {
00053 elevation_map_frame_id = config.elevation_map_frame_id;
00054
00055 sub_elevation_map = nHandle.subscribe(elevation_map_frame_id,1,&ElevationVisualization::map_callback,this);
00056 }
00057 }
00058
00059
00060 void ElevationVisualization::visualize_map(const hector_elevation_msgs::ElevationGrid& elevation_map, tf::StampedTransform local_map_transform)
00061 {
00062 int current_height_level;
00063
00064 for (unsigned i = 0; i < map_marker_array_msg.markers.size(); ++i)
00065 {
00066 map_marker_array_msg.markers[i].points.clear();
00067 }
00068 map_marker_array_msg.markers.clear();
00069
00070
00071
00072 map_marker_array_msg.markers.resize(max_height_levels+1);
00073
00074 for (int index_y = 0; index_y < (int)elevation_map.info.height; ++index_y)
00075 {
00076 for (int index_x = 0; index_x < (int)elevation_map.info.width; ++index_x)
00077 {
00078
00079 if(elevation_map.data[MAP_IDX(elevation_map.info.width, index_x, index_y)] != (int16_t)-elevation_map.info.zero_elevation)
00080 {
00081 geometry_msgs::Point cube_center;
00082 Eigen::Vector2f index_map(index_x, index_y);
00083 Eigen::Vector2f index_world = world_map_transform.getC1Coords(index_map);
00084
00085 cube_center.x = index_world(0);
00086 cube_center.y = index_world(1);
00087 cube_center.z = (elevation_map.data[MAP_IDX(elevation_map.info.width, index_x, index_y)]-elevation_map.info.zero_elevation)*elevation_map.info.resolution_z;
00088 current_height_level = max_height_levels/2+(int)round(std::min(std::max((double)cube_center.z+local_map_transform.getOrigin().z(), -(double)max_height), (double)max_height)*(double)max_height_levels/((double)max_height*2.0f));
00089 map_marker_array_msg.markers[current_height_level].points.push_back(cube_center);
00090
00091 if(use_color_map)
00092 {
00093 double h = (1.0 - std::min(std::max((cube_center.z-min_height)/ (max_height - min_height), 0.0), 1.0)) *color_factor;
00094 map_marker_array_msg.markers[current_height_level].colors.push_back(heightMapColor(h));
00095 }
00096 }
00097 }
00098 }
00099
00100 for (unsigned i = 0; i < map_marker_array_msg.markers.size(); ++i)
00101 {
00102 std::stringstream ss;
00103 ss <<"Level "<<i;
00104 map_marker_array_msg.markers[i].ns = ss.str();
00105 map_marker_array_msg.markers[i].id = i;
00106 map_marker_array_msg.markers[i].header.frame_id = "/map";
00107 map_marker_array_msg.markers[i].header.stamp = elevation_map.header.stamp;
00108 map_marker_array_msg.markers[i].lifetime = ros::Duration();
00109 map_marker_array_msg.markers[i].type = visualization_msgs::Marker::CUBE_LIST;
00110 map_marker_array_msg.markers[i].scale.x = elevation_map.info.resolution_xy;
00111 map_marker_array_msg.markers[i].scale.y = elevation_map.info.resolution_xy;
00112 map_marker_array_msg.markers[i].scale.z = elevation_map.info.resolution_z;
00113 map_marker_array_msg.markers[i].color = marker_color;
00114
00115 if (map_marker_array_msg.markers[i].points.size() > 0)
00116 map_marker_array_msg.markers[i].action = visualization_msgs::Marker::ADD;
00117 else
00118 map_marker_array_msg.markers[i].action = visualization_msgs::Marker::DELETE;
00119 }
00120
00121 }
00122
00123
00124 void ElevationVisualization::map_callback(const hector_elevation_msgs::ElevationGrid& elevation_map)
00125 {
00126
00127 if(map_marker_array_publisher.getNumSubscribers () > 0)
00128 {
00129 tf::TransformListener listener;
00130 tf::StampedTransform local_map_transform;
00131
00132
00133 try
00134 {
00135 listener.waitForTransform("/base_footprint", "/map",ros::Time(0),ros::Duration(5.0));
00136 listener.lookupTransform("/base_footprint", "/map", ros::Time(0), local_map_transform);
00137 }
00138 catch (tf::TransformException ex)
00139 {
00140 ROS_ERROR("%s",ex.what());
00141 return;
00142 }
00143
00144
00145 nav_msgs::MapMetaData map_meta;
00146 map_meta.resolution = elevation_map.info.resolution_xy;
00147 map_meta.height = elevation_map.info.height;
00148 map_meta.width = elevation_map.info.width;
00149 map_meta.origin = elevation_map.info.origin;
00150
00151 world_map_transform.setTransforms(map_meta);
00152
00153
00154 visualize_map(elevation_map, local_map_transform);
00155
00156
00157
00158 map_marker_array_publisher.publish(map_marker_array_msg);
00159 }
00160 }
00161
00162 void ElevationVisualization::sys_message_callback(const std_msgs::String& string)
00163 {
00164 ROS_DEBUG("sysMsgCallback, msg contents: %s", string.data.c_str());
00165
00166 if (string.data == "reset")
00167 {
00168 ROS_INFO("reset");
00169
00170 for (unsigned i = 0; i < map_marker_array_msg.markers.size(); ++i)
00171 {
00172 map_marker_array_msg.markers[i].points.clear();
00173 }
00174 map_marker_array_msg.markers.clear();
00175 }
00176 }
00177
00178 std_msgs::ColorRGBA ElevationVisualization::heightMapColor(double h)
00179 {
00180
00181 std_msgs::ColorRGBA color;
00182 color.a = 1.0;
00183
00184
00185 double s = 1.0;
00186 double v = 1.0;
00187
00188 h -= floor(h);
00189 h *= 6;
00190 int i;
00191 double m, n, f;
00192
00193 i = floor(h);
00194 f = h - i;
00195 if (!(i & 1))
00196 f = 1 - f;
00197 m = v * (1 - s);
00198 n = v * (1 - s * f);
00199
00200 switch (i) {
00201 case 6:
00202 case 0:
00203 color.r = v; color.g = n; color.b = m;
00204 break;
00205 case 1:
00206 color.r = n; color.g = v; color.b = m;
00207 break;
00208 case 2:
00209 color.r = m; color.g = v; color.b = n;
00210 break;
00211 case 3:
00212 color.r = m; color.g = n; color.b = v;
00213 break;
00214 case 4:
00215 color.r = n; color.g = m; color.b = v;
00216 break;
00217 case 5:
00218 color.r = v; color.g = m; color.b = n;
00219 break;
00220 default:
00221 color.r = 1; color.g = 0.5; color.b = 0.5;
00222 break;
00223 }
00224
00225 return color;
00226 }
00227
00228
00229