00001 #include <iostream>
00002 #include <interactive_markers/tools.h>
00003 #include <jsk_interactive_marker/point_cloud_config_marker.h>
00004 #include <jsk_interactive_marker/interactive_marker_utils.h>
00005
00006 using namespace std;
00007
00008 visualization_msgs::Marker PointCloudConfigMarker::makeBoxMarker(geometry_msgs::Vector3 size){
00009 visualization_msgs::Marker marker;
00010 marker.type = visualization_msgs::Marker::CUBE;
00011 marker.scale = size;
00012
00013 marker.color.r = 0.5;
00014 marker.color.g = 0.5;
00015 marker.color.b = 0.5;
00016 marker.color.a = 0.3;
00017 return marker;
00018 }
00019
00020 visualization_msgs::Marker PointCloudConfigMarker::makeTextMarker(geometry_msgs::Vector3 size){
00021 visualization_msgs::Marker marker;
00022 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00023 marker.text = "hello world";
00024 marker.scale.z = 0.1;
00025 marker.scale.y = 0.1;
00026 marker.scale.x = 0.1;
00027 marker.color.r = 0.0;
00028 marker.color.g = 0.0;
00029 marker.color.b = 0.0;
00030 marker.color.a = 1.0;
00031 return marker;
00032 }
00033
00034 visualization_msgs::InteractiveMarker PointCloudConfigMarker::makeBoxInteractiveMarker(MarkerControlConfig mconfig, std::string name){
00035 visualization_msgs::InteractiveMarker mk;
00036 mk.header.frame_id = base_frame;
00037 if (latest_feedback_) {
00038 mk.pose = latest_feedback_->pose;
00039 }
00040
00041 std::string description;
00042 std::stringstream ss;
00043 ss << "size: (" << mconfig.size.x
00044 << ", " << mconfig.size.y
00045 << ", " << mconfig.size.z << ")" << std::endl;
00046 ss << "resolution: " << mconfig.resolution_ << std::endl;
00047 description = ss.str();
00048
00049 mk.header.stamp = ros::Time(0);
00050 mk.name = name;
00051
00052
00053 mk.scale = 1.0;
00054 mk.scale = max(mconfig.size.x, max(mconfig.size.y, mconfig.size.z));
00055
00056 visualization_msgs::InteractiveMarkerControl controlBox;
00057 controlBox.always_visible = true;
00058 controlBox.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00059 controlBox.markers.push_back( makeBoxMarker(mconfig.size) );
00060 mk.controls.push_back( controlBox );
00061
00062 visualization_msgs::InteractiveMarkerControl textBox;
00063 textBox.always_visible = true;
00064 textBox.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00065 visualization_msgs::Marker text_marker = makeTextMarker(mconfig.size);
00066 text_marker.text = description;
00067 textBox.markers.push_back( text_marker );
00068 mk.controls.push_back( textBox );
00069
00070 visualization_msgs::InteractiveMarkerControl controlArrow;
00071 controlArrow.always_visible = true;
00072 controlArrow.orientation.w = 1;
00073 controlArrow.orientation.x = 1;
00074 controlArrow.orientation.y = 0;
00075 controlArrow.orientation.z = 0;
00076
00077 controlArrow.name = "move_x";
00078 controlArrow.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00079 mk.controls.push_back(controlArrow);
00080
00081 controlArrow.orientation.w = 1;
00082 controlArrow.orientation.x = 0;
00083 controlArrow.orientation.y = 1;
00084 controlArrow.orientation.z = 0;
00085 controlArrow.name = "move_z";
00086 controlArrow.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00087 mk.controls.push_back(controlArrow);
00088
00089 controlArrow.orientation.w = 1;
00090 controlArrow.orientation.x = 0;
00091 controlArrow.orientation.y = 0;
00092 controlArrow.orientation.z = 1;
00093 controlArrow.name = "move_y";
00094 controlArrow.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00095 mk.controls.push_back(controlArrow);
00096
00097 return mk;
00098 }
00099
00100 interactive_markers::MenuHandler PointCloudConfigMarker::makeMenuHandler(){
00101 interactive_markers::MenuHandler mh;
00102 mh.insert("Add Point Cloud ROI", boost::bind( &PointCloudConfigMarker::publishMarkerMsg, this, _1));
00103
00104 mh.insert("Start", boost::bind( &PointCloudConfigMarker::publishMarkerMsg, this, _1));
00105
00106 mh.insert("Stop", boost::bind( &PointCloudConfigMarker::publishMarkerMsg, this, _1));
00107
00108
00109
00110 resolution_menu_ = mh.insert( "Resolution" );
00111 resolution_20cm_menu_ = mh.insert( resolution_menu_, "20cm", boost::bind( &PointCloudConfigMarker::changeResolutionCb, this, _1));
00112 mh.setCheckState( resolution_20cm_menu_, interactive_markers::MenuHandler::UNCHECKED );
00113
00114
00115 resolution_10cm_menu_ = mh.insert( resolution_menu_, "10cm", boost::bind( &PointCloudConfigMarker::changeResolutionCb, this, _1));
00116 mh.setCheckState( resolution_10cm_menu_, interactive_markers::MenuHandler::UNCHECKED );
00117
00118
00119 resolution_5cm_menu_ = mh.insert( resolution_menu_, "5cm", boost::bind( &PointCloudConfigMarker::changeResolutionCb, this, _1));
00120 mh.setCheckState( resolution_5cm_menu_, interactive_markers::MenuHandler::CHECKED );
00121 marker_control_config.resolution_ = 0.05;
00122 checked_resolution_menu_ = resolution_5cm_menu_;
00123
00124 box_size_menu_ = mh.insert( "Box Size" );
00125
00126 box_size_100_menu_ = mh.insert( box_size_menu_, "100 x 100 x 100", boost::bind( &PointCloudConfigMarker::changeBoxSizeCb, this, _1));
00127 mh.setCheckState( box_size_100_menu_, interactive_markers::MenuHandler::UNCHECKED );
00128
00129
00130 box_size_50_menu_ = mh.insert( box_size_menu_, "50 x 50 x 50", boost::bind( &PointCloudConfigMarker::changeBoxSizeCb, this, _1));
00131 mh.setCheckState( box_size_50_menu_, interactive_markers::MenuHandler::UNCHECKED );
00132
00133 checked_box_size_menu_ = box_size_50_menu_;
00134
00135
00136 box_size_25_menu_ = mh.insert( box_size_menu_, "25 x 25 x 25", boost::bind( &PointCloudConfigMarker::changeBoxSizeCb, this, _1));
00137 mh.setCheckState( box_size_25_menu_, interactive_markers::MenuHandler::UNCHECKED );
00138
00139 mh.insert("Cancel", boost::bind( &PointCloudConfigMarker::cancelCb, this, _1));
00140 mh.insert("Clear All Point Cloud", boost::bind( &PointCloudConfigMarker::clearCb, this, _1));
00141
00142
00143
00144
00145 return mh;
00146 }
00147
00148 void PointCloudConfigMarker::publishCurrentPose(const geometry_msgs::PoseStamped::ConstPtr &pose)
00149 {
00150 current_pose_pub_.publish(pose);
00151 }
00152
00153 void PointCloudConfigMarker::publishCurrentPose(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
00154 {
00155 geometry_msgs::PoseStamped pose_stamped;
00156 pose_stamped.header = feedback->header;
00157 pose_stamped.pose = feedback->pose;
00158 current_pose_pub_.publish(pose_stamped);
00159 }
00160
00161 void PointCloudConfigMarker::moveBoxCb( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
00162 {
00163
00164 publishCurrentPose(feedback);
00165 latest_feedback_ = feedback;
00166 }
00167
00168 void PointCloudConfigMarker::changeResolutionCb( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00169 menu_handler.setCheckState( checked_resolution_menu_ , interactive_markers::MenuHandler::UNCHECKED );
00170 checked_resolution_menu_ = feedback->menu_entry_id;
00171
00172 if(feedback->menu_entry_id == resolution_10cm_menu_){
00173 marker_control_config.resolution_ = 0.1;
00174
00175 }else if(feedback->menu_entry_id == resolution_5cm_menu_){
00176 marker_control_config.resolution_ = 0.05;
00177 }
00178 else if(feedback->menu_entry_id == resolution_20cm_menu_){
00179 marker_control_config.resolution_ = 0.2;
00180 }
00181 std::cout <<"resolution:" << marker_control_config.resolution_ << std::endl;
00182
00183 menu_handler.setCheckState( feedback->menu_entry_id , interactive_markers::MenuHandler::CHECKED );
00184
00185 menu_handler.reApply( *server_ );
00186 server_->applyChanges();
00187 latest_feedback_ = feedback;
00188
00189 }
00190
00191
00192 void PointCloudConfigMarker::changeBoxResolution(const std_msgs::Float32::ConstPtr &msg){
00193 marker_control_config.resolution_ = msg->data;
00194 updateBoxInteractiveMarker();
00195 }
00196
00197 void PointCloudConfigMarker::changeBoxSize(geometry_msgs::Vector3 size){
00198 marker_control_config.size = size;
00199 updateBoxInteractiveMarker();
00200 }
00201
00202
00203 void PointCloudConfigMarker::changeBoxSizeCb( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00204 menu_handler.setCheckState( checked_resolution_menu_ , interactive_markers::MenuHandler::UNCHECKED );
00205 checked_resolution_menu_ = feedback->menu_entry_id;
00206
00207 menu_handler.setCheckState( feedback->menu_entry_id , interactive_markers::MenuHandler::CHECKED );
00208
00209 geometry_msgs::Vector3 vec;
00210 if(feedback->menu_entry_id == box_size_100_menu_){
00211 vec.x = 1.0;
00212 vec.y = 1.0;
00213 vec.z = 1.0;
00214 changeBoxSize(vec);
00215 }else if(feedback->menu_entry_id == box_size_50_menu_){
00216
00217 }
00218 }
00219
00220
00221
00222
00223 visualization_msgs::Marker PointCloudConfigMarker::makeMarkerMsg( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00224 visualization_msgs::Marker marker;
00225 marker.type = visualization_msgs::Marker::CUBE;
00226 marker.pose = feedback->pose;
00227 marker.scale.x = marker_control_config.size.x;
00228 marker.scale.y = marker_control_config.size.y;
00229 marker.scale.z = marker_control_config.size.z;
00230 marker.color.r = marker_control_config.resolution_;
00231 marker.color.g = marker_control_config.resolution_ * 10;
00232 if(marker.color.g > 1.0){marker.color.g = 1.0;}
00233 marker.color.b = marker_control_config.resolution_ * 10;
00234 if(marker.color.b > 1.0){marker.color.b = 1.0;}
00235 marker.color.a = 0.1;
00236 marker.header = feedback->header;
00237 return marker;
00238 }
00239
00240 void PointCloudConfigMarker::publishMarkerMsg( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00241 visualization_msgs::Marker marker = makeMarkerMsg(feedback);
00242 marker.id = marker_control_config.marker_id++;
00243 pub_.publish(marker);
00244 latest_feedback_ = feedback;
00245 }
00246
00247
00248 void PointCloudConfigMarker::cancelCb( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00249 if(marker_control_config.marker_id == 0){
00250 return;
00251 }
00252 visualization_msgs::Marker marker = makeMarkerMsg(feedback);
00253 marker.id = --marker_control_config.marker_id;
00254 marker.action = visualization_msgs::Marker::DELETE;
00255 pub_.publish(marker);
00256 latest_feedback_ = feedback;
00257 }
00258
00259
00260 void PointCloudConfigMarker::clearBox(){
00261 marker_control_config.marker_id = 0;
00262
00263 visualization_msgs::Marker marker = makeMarkerMsg(latest_feedback_);
00264 marker.id = -1;
00265 marker.action = visualization_msgs::Marker::DELETE;
00266 pub_.publish(marker);
00267 }
00268
00269 void PointCloudConfigMarker::clearBoxCB( const std_msgs::Empty::ConstPtr &msg) {
00270 clearBox();
00271 }
00272
00273 void PointCloudConfigMarker::clearCb( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00274 latest_feedback_ = feedback;
00275 clearBox();
00276 }
00277
00278 void PointCloudConfigMarker::updateBoxInteractiveMarker(){
00279 visualization_msgs::InteractiveMarker boxIM = makeBoxInteractiveMarker(marker_control_config, marker_name);
00280
00281 server_->insert(boxIM,
00282 boost::bind( &PointCloudConfigMarker::moveBoxCb, this, _1 ));
00283 menu_handler.apply(*server_, marker_name);
00284 server_->applyChanges();
00285 }
00286
00287 void PointCloudConfigMarker::updatePoseCB(const geometry_msgs::PoseStamped::ConstPtr &pose) {
00288
00289 server_->setPose(marker_name, pose->pose);
00290 server_->applyChanges();
00291 publishCurrentPose(pose);
00292
00293 visualization_msgs::InteractiveMarkerFeedback::Ptr feedback(new visualization_msgs::InteractiveMarkerFeedback);
00294 feedback->pose = pose->pose;
00295 feedback->header = pose->header;
00296 latest_feedback_ = feedback;
00297 }
00298
00299 void PointCloudConfigMarker::addBoxCB(const std_msgs::Empty::ConstPtr &msg) {
00300 ROS_INFO("add!");
00301 visualization_msgs::Marker marker = makeMarkerMsg(latest_feedback_);
00302 marker.id = marker_control_config.marker_id++;
00303 pub_.publish(marker);
00304 }
00305
00306 PointCloudConfigMarker::PointCloudConfigMarker () : nh_(), pnh_("~") {
00307 pnh_.param("server_name", server_name, std::string ("") );
00308 pnh_.param("size", size_, 1.0 );
00309 pnh_.param("marker_name", marker_name, std::string ("point_cloud_config_marker") );
00310 pnh_.param("base_frame", base_frame, std::string("/pelvis") );
00311
00312 if ( server_name == "" ) {
00313 server_name = ros::this_node::getName();
00314 }
00315 server_.reset( new interactive_markers::InteractiveMarkerServer(server_name));
00316
00317 pub_ = pnh_.advertise<visualization_msgs::Marker> ("get", 1);
00318 current_pose_pub_ = pnh_.advertise<geometry_msgs::PoseStamped> ("current_pose", 1);
00319 pose_update_sub_ = pnh_.subscribe("update_pose", 1, &PointCloudConfigMarker::updatePoseCB,
00320 this);
00321 add_box_sub_ = pnh_.subscribe("add_box", 1, &PointCloudConfigMarker::addBoxCB, this);
00322 clear_box_sub_ = pnh_.subscribe("clear_box", 1, &PointCloudConfigMarker::clearBoxCB, this);
00323 change_box_size_sub_ = pnh_.subscribe("change_size", 1, &PointCloudConfigMarker::changeBoxSize, this);
00324 change_box_resolution_sub_ = pnh_.subscribe("change_resolution", 1, &PointCloudConfigMarker::changeBoxResolution, this);
00325 menu_handler = makeMenuHandler();
00326
00327 marker_control_config = MarkerControlConfig(size_);
00328
00329 updateBoxInteractiveMarker();
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 return;
00344
00345 }
00346
00347
00348 int main(int argc, char** argv)
00349 {
00350 ros::init(argc, argv, "point_cloud_config_marker");
00351 PointCloudConfigMarker pccm;
00352 ros::spin();
00353 return 0;
00354 }
00355
00356