00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <sensor_msgs/PointCloud2.h>
00045
00046
00047 #include <pcl/ros/conversions.h>
00048 #include <pcl/point_cloud.h>
00049 #include <pcl/point_types.h>
00050
00051
00052
00053
00054 #include <ros/ros.h>
00055
00056 #include <interactive_markers/interactive_marker_server.h>
00057 #include <interactive_markers/menu_handler.h>
00058
00059 #include <tf/transform_broadcaster.h>
00060 #include <tf/tf.h>
00061
00062 #include <math.h>
00063
00064 using namespace visualization_msgs;
00065
00066
00067
00068 boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;
00069 float marker_pos = 0;
00070 interactive_markers::MenuHandler menu_handler;
00071 ros::Publisher pub;
00072
00073
00074
00075 void frameCallback(const ros::TimerEvent&)
00076 {
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 }
00095
00096
00097
00098 void processFeedback( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00099 {
00100 std::ostringstream s;
00101 s << "Feedback from marker '" << feedback->marker_name << "' "
00102 << " / control '" << feedback->control_name << "'";
00103
00104 std::ostringstream mouse_point_ss;
00105 if( feedback->mouse_point_valid )
00106 {
00107 mouse_point_ss << " at " << feedback->mouse_point.x
00108 << ", " << feedback->mouse_point.y
00109 << ", " << feedback->mouse_point.z
00110 << " in frame " << feedback->header.frame_id;
00111 }
00112
00113 switch ( feedback->event_type )
00114 {
00115
00116
00117
00118
00119
00120
00121
00122
00123 case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
00124 pcl::PointCloud<pcl::PointXYZ> pc;
00125 pcl::PointXYZ pt;
00126 pt.x = feedback->pose.position.x; pt.y = feedback->pose.position.y; pt.z = feedback->pose.position.z;
00127 pc.points.push_back(pt);
00128
00129 sensor_msgs::PointCloud2 pcmsg_out;
00130 pcl::toROSMsg(pc, pcmsg_out);
00131 pcmsg_out.header.stamp = ros::Time::now();
00132 pcmsg_out.header.frame_id = "/atc/vehicle/center_bumper";
00133
00134 pub.publish(pcmsg_out);
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 break;
00150
00151
00152
00153
00154
00155
00156
00157
00158 }
00159
00160 server->applyChanges();
00161 }
00162
00163
00164
00165 void alignMarker( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00166 {
00167 geometry_msgs::Pose pose = feedback->pose;
00168
00169 pose.position.x = round(pose.position.x-0.5)+0.5;
00170 pose.position.y = round(pose.position.y-0.5)+0.5;
00171
00172 ROS_INFO_STREAM( feedback->marker_name << ":"
00173 << " aligning position = "
00174 << feedback->pose.position.x
00175 << ", " << feedback->pose.position.y
00176 << ", " << feedback->pose.position.z
00177 << " to "
00178 << pose.position.x
00179 << ", " << pose.position.y
00180 << ", " << pose.position.z );
00181
00182 server->setPose( feedback->marker_name, pose );
00183 server->applyChanges();
00184 }
00185
00186
00187 double rand( double min, double max )
00188 {
00189 double t = (double)rand() / (double)RAND_MAX;
00190 return min + t*(max-min);
00191 }
00192
00193
00194 Marker makeBox( InteractiveMarker &msg )
00195 {
00196 Marker marker;
00197
00198 marker.type = Marker::SPHERE;
00199 marker.scale.x = msg.scale * 0.45;
00200 marker.scale.y = msg.scale * 0.45;
00201 marker.scale.z = msg.scale * 0.45;
00202 marker.color.r = 0;
00203 marker.color.g = 0.7;
00204 marker.color.b = 0;
00205 marker.color.a = 0.6;
00206
00207 return marker;
00208 }
00209
00210 InteractiveMarkerControl& makeBoxControl( InteractiveMarker &msg )
00211 {
00212 InteractiveMarkerControl control;
00213 control.always_visible = true;
00214 control.markers.push_back( makeBox(msg) );
00215 msg.controls.push_back( control );
00216
00217 return msg.controls.back();
00218 }
00219
00220
00221 void saveMarker( InteractiveMarker int_marker )
00222 {
00223 server->insert(int_marker);
00224 server->setCallback(int_marker.name, &processFeedback);
00225 }
00226
00228
00229
00230 void make6DofMarker( bool fixed )
00231 {
00232 InteractiveMarker int_marker;
00233 int_marker.header.frame_id = "/atc/vehicle/center_bumper";
00234 int_marker.pose.position.x = 2;
00235 int_marker.pose.position.y = 0;
00236 int_marker.pose.position.z = 0.5;
00237 int_marker.scale = 0.5;
00238
00239 int_marker.name = "Fovetation Control Target";
00240 int_marker.description = "Foveation_control will try \nto aim the PTU towards\n the marker";
00241
00242
00243 makeBoxControl(int_marker);
00244 InteractiveMarkerControl control;
00245
00246 if ( fixed )
00247 {
00248
00249
00250
00251 }
00252
00253 control.orientation.w = 1;
00254 control.orientation.x = 1;
00255 control.orientation.y = 0;
00256 control.orientation.z = 0;
00257
00258
00259
00260 control.name = "move_x";
00261 control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00262 int_marker.controls.push_back(control);
00263
00264 control.orientation.w = 1;
00265 control.orientation.x = 0;
00266 control.orientation.y = 1;
00267 control.orientation.z = 0;
00268
00269
00270
00271 control.name = "move_z";
00272 control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00273 int_marker.controls.push_back(control);
00274
00275 control.orientation.w = 1;
00276 control.orientation.x = 0;
00277 control.orientation.y = 0;
00278 control.orientation.z = 1;
00279
00280
00281
00282 control.name = "move_y";
00283 control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00284 int_marker.controls.push_back(control);
00285
00286 server->insert(int_marker);
00287 server->setCallback(int_marker.name, &processFeedback);
00288 }
00289
00290
00291
00292 void makeRandomDofMarker( )
00293 {
00294 InteractiveMarker int_marker;
00295 int_marker.header.frame_id = "/base_link";
00296 int_marker.pose.position.y = -3.0 * marker_pos++;;
00297 int_marker.scale = 1;
00298
00299 int_marker.name = "6dof_random_axes";
00300 int_marker.description = "6-DOF\n(Arbitrary Axes)";
00301
00302 makeBoxControl(int_marker);
00303
00304 InteractiveMarkerControl control;
00305
00306 for ( int i=0; i<3; i++ )
00307 {
00308 control.orientation.w = rand(-1,1);
00309 control.orientation.x = rand(-1,1);
00310 control.orientation.y = rand(-1,1);
00311 control.orientation.z = rand(-1,1);
00312 control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00313 int_marker.controls.push_back(control);
00314 control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00315 int_marker.controls.push_back(control);
00316 }
00317
00318 server->insert(int_marker);
00319 server->setCallback(int_marker.name, &processFeedback);
00320 }
00321
00322
00323
00324
00325 void makeViewFacingMarker( )
00326 {
00327 InteractiveMarker int_marker;
00328 int_marker.header.frame_id = "/base_link";
00329 int_marker.pose.position.y = -3.0 * marker_pos++;;
00330 int_marker.scale = 1;
00331
00332 int_marker.name = "view_facing";
00333 int_marker.description = "View Facing 6-DOF";
00334
00335 InteractiveMarkerControl control;
00336
00337
00338 control.orientation_mode = InteractiveMarkerControl::VIEW_FACING;
00339 control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00340 control.orientation.w = 1;
00341 control.name = "rotate";
00342
00343 int_marker.controls.push_back(control);
00344
00345
00346
00347 control.orientation_mode = InteractiveMarkerControl::VIEW_FACING;
00348 control.interaction_mode = InteractiveMarkerControl::MOVE_PLANE;
00349 control.independent_marker_orientation = true;
00350 control.name = "move";
00351
00352 control.markers.push_back( makeBox(int_marker) );
00353 control.always_visible = true;
00354
00355 int_marker.controls.push_back(control);
00356
00357 server->insert(int_marker);
00358 server->setCallback(int_marker.name, &processFeedback);
00359 }
00360
00361
00362
00363
00364 void makeQuadrocopterMarker( )
00365 {
00366 InteractiveMarker int_marker;
00367 int_marker.header.frame_id = "/base_link";
00368 int_marker.pose.position.y = -3.0 * marker_pos++;;
00369 int_marker.scale = 1;
00370
00371 int_marker.name = "quadrocopter";
00372 int_marker.description = "Quadrocopter";
00373
00374 makeBoxControl(int_marker);
00375
00376 InteractiveMarkerControl control;
00377
00378 control.orientation.w = 1;
00379 control.orientation.x = 0;
00380 control.orientation.y = 1;
00381 control.orientation.z = 0;
00382 control.interaction_mode = InteractiveMarkerControl::MOVE_ROTATE;
00383 int_marker.controls.push_back(control);
00384 control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00385 int_marker.controls.push_back(control);
00386
00387 server->insert(int_marker);
00388 server->setCallback(int_marker.name, &processFeedback);
00389 }
00390
00391
00392
00393 void makeChessPieceMarker( )
00394 {
00395 InteractiveMarker int_marker;
00396 int_marker.header.frame_id = "/base_link";
00397 int_marker.pose.position.y = -3.0 * marker_pos++;;
00398 int_marker.scale = 1;
00399
00400 int_marker.name = "chess_piece";
00401 int_marker.description = "Chess Piece\n(2D Move + Alignment)";
00402
00403 InteractiveMarkerControl control;
00404
00405 control.orientation.w = 1;
00406 control.orientation.x = 0;
00407 control.orientation.y = 1;
00408 control.orientation.z = 0;
00409 control.interaction_mode = InteractiveMarkerControl::MOVE_PLANE;
00410 int_marker.controls.push_back(control);
00411
00412
00413 control.markers.push_back( makeBox(int_marker) );
00414 control.always_visible = true;
00415 int_marker.controls.push_back(control);
00416
00417
00418 server->insert(int_marker);
00419 server->setCallback(int_marker.name, &processFeedback);
00420
00421
00422 server->setCallback(int_marker.name, &alignMarker, visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE );
00423 }
00424
00425
00426
00427 void makePanTiltMarker( )
00428 {
00429 InteractiveMarker int_marker;
00430 int_marker.header.frame_id = "/base_link";
00431 int_marker.pose.position.y = -3.0 * marker_pos++;;
00432 int_marker.scale = 1;
00433
00434 int_marker.name = "pan_tilt";
00435 int_marker.description = "Pan / Tilt";
00436
00437 makeBoxControl(int_marker);
00438
00439 InteractiveMarkerControl control;
00440
00441 control.orientation.w = 1;
00442 control.orientation.x = 0;
00443 control.orientation.y = 1;
00444 control.orientation.z = 0;
00445 control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00446 control.orientation_mode = InteractiveMarkerControl::FIXED;
00447 int_marker.controls.push_back(control);
00448
00449 control.orientation.w = 1;
00450 control.orientation.x = 0;
00451 control.orientation.y = 0;
00452 control.orientation.z = 1;
00453 control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00454 control.orientation_mode = InteractiveMarkerControl::INHERIT;
00455 int_marker.controls.push_back(control);
00456
00457 server->insert(int_marker);
00458 server->setCallback(int_marker.name, &processFeedback);
00459 }
00460
00461
00462
00463 void makeMenuMarker()
00464 {
00465 InteractiveMarker int_marker;
00466 int_marker.header.frame_id = "/base_link";
00467 int_marker.pose.position.y = -3.0 * marker_pos++;;
00468 int_marker.scale = 1;
00469
00470 int_marker.name = "context_menu";
00471 int_marker.description = "Context Menu\n(Right Click)";
00472
00473 InteractiveMarkerControl control;
00474
00475
00476 control.interaction_mode = InteractiveMarkerControl::MENU;
00477 control.description="Options";
00478 control.name = "menu_only_control";
00479 int_marker.controls.push_back(control);
00480
00481
00482 Marker marker = makeBox( int_marker );
00483 control.markers.push_back( marker );
00484 control.always_visible = true;
00485 int_marker.controls.push_back(control);
00486
00487 server->insert(int_marker);
00488 server->setCallback(int_marker.name, &processFeedback);
00489 menu_handler.apply( *server, int_marker.name );
00490 }
00491
00492
00493
00494 void makeMovingMarker()
00495 {
00496 InteractiveMarker int_marker;
00497 int_marker.header.frame_id = "/moving_frame";
00498 int_marker.pose.position.y = -3.0 * marker_pos++;;
00499 int_marker.scale = 1;
00500
00501 int_marker.name = "moving";
00502 int_marker.description = "Marker Attached to a\nMoving Frame";
00503
00504 InteractiveMarkerControl control;
00505
00506 control.orientation.w = 1;
00507 control.orientation.x = 1;
00508 control.orientation.y = 0;
00509 control.orientation.z = 0;
00510 control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00511 int_marker.controls.push_back(control);
00512
00513 control.interaction_mode = InteractiveMarkerControl::MOVE_PLANE;
00514 control.always_visible = true;
00515 control.markers.push_back( makeBox(int_marker) );
00516 int_marker.controls.push_back(control);
00517
00518 server->insert(int_marker);
00519 server->setCallback(int_marker.name, &processFeedback);
00520 }
00521
00522
00523
00524 int main(int argc, char** argv)
00525 {
00526 ros::init(argc, argv, "foveation_control_target_generator");
00527 ros::NodeHandle n;
00528
00529
00530 pub = n.advertise<sensor_msgs::PointCloud2>("/target", 1);
00531
00532
00533
00534
00535 server.reset( new interactive_markers::InteractiveMarkerServer("bytarget/im","",false) );
00536
00537 ros::Duration(0.1).sleep();
00538
00539
00540 menu_handler.insert( "First Entry", &processFeedback );
00541 menu_handler.insert( "Second Entry", &processFeedback );
00542 interactive_markers::MenuHandler::EntryHandle sub_menu_handle = menu_handler.insert( "Submenu" );
00543 menu_handler.insert( sub_menu_handle, "First Entry", &processFeedback );
00544 menu_handler.insert( sub_menu_handle, "Second Entry", &processFeedback );
00545
00546
00547 make6DofMarker( true );
00548
00549
00550
00551
00552
00553
00554
00555
00556 server->applyChanges();
00557
00558 ros::spin();
00559
00560 server.reset();
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00611
00612
00614
00615
00616
00617
00618
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00631
00632
00633
00634
00637
00644
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00690
00692
00693
00694
00695
00696
00699
00701
00708
00709
00710
00715
00722
00724
00727