laser3d_interactive_control.cpp
Go to the documentation of this file.
00001 /**************************************************************************************************
00002  Software License Agreement (BSD License)
00003 
00004  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
00005  All rights reserved.
00006 
00007  Redistribution and use in source and binary forms, with or without modification, are permitted
00008  provided that the following conditions are met:
00009 
00010   *Redistributions of source code must retain the above copyright notice, this list of
00011    conditions and the following disclaimer.
00012   *Redistributions in binary form must reproduce the above copyright notice, this list of
00013    conditions and the following disclaimer in the documentation and/or other materials provided
00014    with the distribution.
00015   *Neither the name of the University of Aveiro nor the names of its contributors may be used to
00016    endorse or promote products derived from this software without specific prior written permission.
00017  
00018  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
00019  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00020  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
00021  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00024  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00025  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 ***************************************************************************************************/
00035 #include <ros/ros.h>
00036 #include <interactive_markers/interactive_marker_server.h>
00037 #include <interactive_markers/menu_handler.h>
00038 #include <tf/transform_broadcaster.h>
00039 #include <tf/tf.h>
00040 #include <math.h>
00041 #include <sensor_msgs/JointState.h>
00042 
00043 using namespace visualization_msgs;
00044 // using namespace tf;
00045 
00046 bool pos_control=true;
00047 
00048 
00049 // %Tag(vars)%
00050 boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;
00051 float marker_pos = 0;
00052 interactive_markers::MenuHandler menu_handler;
00053 ros::Publisher pub;
00054 // %EndTag(vars)%
00055 
00056 // %Tag(frameCallback)%
00057 void frameCallback(const ros::TimerEvent&)
00058 {
00059         //static uint32_t counter = 0;
00060 
00061         //static tf::TransformBroadcaster br;
00062 
00063         //tf::Transform t;
00064 
00065         //ros::Time time = ros::Time::now();
00066 
00067         //t.setOrigin(tf::Vector3(0.0, 0.0, sin(float(counter)/140.0) * 2.0));
00068         //t.setRotation(tf::Quaternion(0.0, 0.0, 0.0, 1.0));
00069         //br.sendTransform(tf::StampedTransform(t, time, "base_link", "moving_frame"));
00070 
00071         //t.setOrigin(tf::Vector3(0.0, 0.0, 0.0));
00072         //t.setRotation(tf::createQuaternionFromRPY(0.0, float(counter)/140.0, 0.0));
00073         //br.sendTransform(tf::StampedTransform(t, time, "base_link", "rotating_frame"));
00074 
00075         //++counter;
00076 }
00077 // %EndTag(frameCallback)%
00078 
00079 // %Tag(processFeedback)%
00080 void processFeedback( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00081 {
00082         std::ostringstream s;
00083         s << "Feedback from marker '" << feedback->marker_name << "' "
00084                 << " / control '" << feedback->control_name << "'";
00085 
00086         std::ostringstream mouse_point_ss;
00087         if( feedback->mouse_point_valid )
00088         {
00089                 mouse_point_ss << " at " << feedback->mouse_point.x
00090                         << ", " << feedback->mouse_point.y
00091                         << ", " << feedback->mouse_point.z
00092                         << " in frame " << feedback->header.frame_id;
00093         }
00094 
00095         switch ( feedback->event_type )
00096         {
00097                 //case visualization_msgs::InteractiveMarkerFeedback::BUTTON_CLICK:
00098                 //ROS_INFO_STREAM( s.str() << ": button click" << mouse_point_ss.str() << "." );
00099                 //break;
00100 
00101                 case visualization_msgs::InteractiveMarkerFeedback::MENU_SELECT:
00102                         ROS_INFO_STREAM( s.str() << ": menu item " << feedback->menu_entry_id << " clicked" << mouse_point_ss.str() << "." );
00103                         if (feedback->menu_entry_id==1)
00104                         {
00105                                 pos_control=true;
00106                                 ROS_INFO("Selected pos control");
00107                                 sensor_msgs::JointState joint_state;
00108                                 joint_state.header.stamp = ros::Time::now();
00109                                 joint_state.name.resize(1);
00110                                 joint_state.position.resize(1);
00111                                 joint_state.velocity.resize(0);
00112                                 joint_state.name[0] =ros::names::remap("shaft");
00113                                 joint_state.position[0] = 0;
00114                                 pub.publish(joint_state);
00115 
00116 
00117                         }
00118                         else if (feedback->menu_entry_id==3)
00119                         {
00120                                 //set 30 rpm
00121                                 pos_control=false;
00122                                 ROS_INFO("Selected speed control");
00123                                 sensor_msgs::JointState joint_state;
00124                                 joint_state.header.stamp = ros::Time::now();
00125                                 joint_state.name.resize(1);
00126                                 joint_state.position.resize(1);
00127                                 joint_state.velocity.resize(1);
00128                                 joint_state.name[0] =ros::names::remap("shaft");
00129                                 joint_state.position[0] = 0;
00130                                 joint_state.velocity[0] = 30;
00131                                 pub.publish(joint_state);
00132                         }
00133                         else if (feedback->menu_entry_id==4)
00134                         {
00135                                 //set 30 rpm
00136                                 pos_control=false;
00137                                 ROS_INFO("Selected speed control");
00138                                 sensor_msgs::JointState joint_state;
00139                                 joint_state.header.stamp = ros::Time::now();
00140                                 joint_state.name.resize(1);
00141                                 joint_state.position.resize(1);
00142                                 joint_state.velocity.resize(1);
00143                                 joint_state.name[0] =ros::names::remap("shaft");
00144                                 joint_state.position[0] = 0;
00145                                 joint_state.velocity[0] = 60;
00146                                 pub.publish(joint_state);
00147 
00148                         }
00149 
00150                         break;
00151 
00152                 case visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE:
00153 
00154                         #if ROS_VERSION_MINIMUM(1, 8, 0)
00155                                 tf::Quaternion q;
00156                                 tf::Matrix3x3 M(q);
00157                         #else
00158                                 btQuaternion q;
00159                                 btMatrix3x3 M(q);
00160                         #endif
00161 
00162                         
00163                         q[0] = feedback->pose.orientation.x;
00164                         q[1] = feedback->pose.orientation.y;
00165                         q[2] = feedback->pose.orientation.z;
00166                         q[3] = feedback->pose.orientation.w;
00167 
00168                         
00169 
00170                         double r,p,y;
00171                         M.getRPY(r,p,y);
00172                         if (pos_control==true)
00173                         {
00174                                 sensor_msgs::JointState joint_state;
00175                                 joint_state.header.stamp = ros::Time::now();
00176                                 joint_state.name.resize(1);
00177                                 joint_state.position.resize(1);
00178                                 joint_state.velocity.resize(0);
00179                                 joint_state.name[0] =ros::names::remap("shaft");
00180                                 joint_state.position[0] = y;
00181                                 pub.publish(joint_state);
00182                                 ROS_INFO("new pos %f",y);
00183                         }
00184                         //sensor_msgs::JointState joint_state;
00185                         //joint_state.header.stamp = ros::Time::now();
00186                         //joint_state.name.resize(2);
00187                         //joint_state.position.resize(2);
00188                         //joint_state.name[0] =ros::names::remap("pan");
00189                         //joint_state.position[0] = y;
00190                         //joint_state.name[1] =ros::names::remap("tilt");
00191                         //joint_state.position[1] = p;
00192                         //pub.publish(joint_state);
00193 
00194 
00195                         //ROS_INFO_STREAM( s.str() << ": pose changed"
00196                         //<< "\nposition = "
00197                         //<< feedback->pose.position.x
00198                         //<< ", " << feedback->pose.position.y
00199                         //<< ", " << feedback->pose.position.z
00200                         //<< "\norientation = "
00201                         //<< feedback->pose.orientation.w
00202                         //<< ", " << feedback->pose.orientation.x
00203                         //<< ", " << feedback->pose.orientation.y
00204                         //<< ", " << feedback->pose.orientation.z
00205                         //<< "\nframe: " << feedback->header.frame_id
00206                         //<< " time: " << feedback->header.stamp.sec << "sec, "
00207                         //<< feedback->header.stamp.nsec << " nsec" );
00208                         break;
00209 
00210                         //case visualization_msgs::InteractiveMarkerFeedback::MOUSE_DOWN:
00211                         //ROS_INFO_STREAM( s.str() << ": mouse down" << mouse_point_ss.str() << "." );
00212                         //break;
00213 
00214                         //case visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP:
00215                         //ROS_INFO_STREAM( s.str() << ": mouse up" << mouse_point_ss.str() << "." );
00216                         //break;
00217         }
00218 
00219         server->applyChanges();
00220 }
00221 // %EndTag(processFeedback)%
00222 
00223 // %Tag(alignMarker)%
00224 void alignMarker( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00225 {
00226         geometry_msgs::Pose pose = feedback->pose;
00227 
00228         pose.position.x = round(pose.position.x-0.5)+0.5;
00229         pose.position.y = round(pose.position.y-0.5)+0.5;
00230 
00231         ROS_INFO_STREAM( feedback->marker_name << ":"
00232                         << " aligning position = "
00233                         << feedback->pose.position.x
00234                         << ", " << feedback->pose.position.y
00235                         << ", " << feedback->pose.position.z
00236                         << " to "
00237                         << pose.position.x
00238                         << ", " << pose.position.y
00239                         << ", " << pose.position.z );
00240 
00241         server->setPose( feedback->marker_name, pose );
00242         server->applyChanges();
00243 }
00244 // %EndTag(alignMarker)%
00245 
00246 double rand( double min, double max )
00247 {
00248         double t = (double)rand() / (double)RAND_MAX;
00249         return min + t*(max-min);
00250 }
00251 
00252 // %Tag(Box)%
00253 Marker makeBox( InteractiveMarker &msg )
00254 {
00255         Marker marker;
00256 
00257         marker.type = Marker::SPHERE;
00258         marker.scale.x = msg.scale * 0.45;
00259         marker.scale.y = msg.scale * 0.45;
00260         marker.scale.z = msg.scale * 0.45;
00261         marker.color.r = 0;
00262         marker.color.g = 0.7;
00263         marker.color.b = 0;
00264         marker.color.a = 0.6;
00265 
00266         return marker;
00267 }
00268 
00269 InteractiveMarkerControl& makeBoxControl( InteractiveMarker &msg )
00270 {
00271         InteractiveMarkerControl control;
00272         control.always_visible = true;
00273         control.markers.push_back( makeBox(msg) );
00274         msg.controls.push_back( control );
00275 
00276         return msg.controls.back();
00277 }
00278 // %EndTag(Box)%
00279 
00280 void saveMarker( InteractiveMarker int_marker )
00281 {
00282         server->insert(int_marker);
00283         server->setCallback(int_marker.name, &processFeedback);
00284 }
00285 
00287 
00288 // %Tag(6DOF)%
00289 void make6DofMarker( bool fixed )
00290 {
00291         InteractiveMarker int_marker;
00292         int_marker.header.frame_id = "/atc/vehicle/center_bumper";
00293         int_marker.pose.position.x = 2;
00294         int_marker.pose.position.y = 0;
00295         int_marker.pose.position.z = 0.5;
00296         int_marker.scale = 0.5;
00297 
00298         int_marker.name = "Fovetation Control Target";
00299         int_marker.description = "Foveation_control will try \nto aim the PTU towards\n the marker";
00300 
00301         // insert a box
00302         makeBoxControl(int_marker);
00303         InteractiveMarkerControl control;
00304 
00305         if ( fixed )
00306         {
00307                 //int_marker.name += "_fixed";
00308                 //int_marker.description += "\n(fixed orientation)";
00309                 //control.orientation_mode = InteractiveMarkerControl::FIXED;
00310         }
00311 
00312         control.orientation.w = 1;
00313         control.orientation.x = 1;
00314         control.orientation.y = 0;
00315         control.orientation.z = 0;
00316         //control.name = "rotate_x";
00317         //control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00318         //int_marker.controls.push_back(control);
00319         control.name = "move_x";
00320         control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00321         int_marker.controls.push_back(control);
00322 
00323         control.orientation.w = 1;
00324         control.orientation.x = 0;
00325         control.orientation.y = 1;
00326         control.orientation.z = 0;
00327         //control.name = "rotate_z";
00328         //control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00329         //int_marker.controls.push_back(control);
00330         control.name = "move_z";
00331         control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00332         int_marker.controls.push_back(control);
00333 
00334         control.orientation.w = 1;
00335         control.orientation.x = 0;
00336         control.orientation.y = 0;
00337         control.orientation.z = 1;
00338         //control.name = "rotate_y";
00339         //control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00340         //int_marker.controls.push_back(control);
00341         control.name = "move_y";
00342         control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00343         int_marker.controls.push_back(control);
00344 
00345         server->insert(int_marker);
00346         server->setCallback(int_marker.name, &processFeedback);
00347 }
00348 // %EndTag(6DOF)%
00349 
00350 // %Tag(RandomDof)%
00351 void makeRandomDofMarker( )
00352 {
00353         InteractiveMarker int_marker;
00354         int_marker.header.frame_id = "/base_link";
00355         int_marker.pose.position.y = -3.0 * marker_pos++;;
00356         int_marker.scale = 1;
00357 
00358         int_marker.name = "6dof_random_axes";
00359         int_marker.description = "6-DOF\n(Arbitrary Axes)";
00360 
00361         makeBoxControl(int_marker);
00362 
00363         InteractiveMarkerControl control;
00364 
00365         for ( int i=0; i<3; i++ )
00366         {
00367                 control.orientation.w = rand(-1,1);
00368                 control.orientation.x = rand(-1,1);
00369                 control.orientation.y = rand(-1,1);
00370                 control.orientation.z = rand(-1,1);
00371                 control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00372                 int_marker.controls.push_back(control);
00373                 control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00374                 int_marker.controls.push_back(control);
00375         }
00376 
00377         server->insert(int_marker);
00378         server->setCallback(int_marker.name, &processFeedback);
00379 }
00380 // %EndTag(RandomDof)%
00381 
00382 
00383 // %Tag(ViewFacing)%
00384 void makeViewFacingMarker( )
00385 {
00386         InteractiveMarker int_marker;
00387         int_marker.header.frame_id = "/base_link";
00388         int_marker.pose.position.y = -3.0 * marker_pos++;;
00389         int_marker.scale = 1;
00390 
00391         int_marker.name = "view_facing";
00392         int_marker.description = "View Facing 6-DOF";
00393 
00394         InteractiveMarkerControl control;
00395 
00396         // make a control that rotates around the view axis
00397         control.orientation_mode = InteractiveMarkerControl::VIEW_FACING;
00398         control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00399         control.orientation.w = 1;
00400         control.name = "rotate";
00401 
00402         int_marker.controls.push_back(control);
00403 
00404         // create a box in the center which should not be view facing,
00405         // but move in the camera plane.
00406         control.orientation_mode = InteractiveMarkerControl::VIEW_FACING;
00407         control.interaction_mode = InteractiveMarkerControl::MOVE_PLANE;
00408         control.independent_marker_orientation = true;
00409         control.name = "move";
00410 
00411         control.markers.push_back( makeBox(int_marker) );
00412         control.always_visible = true;
00413 
00414         int_marker.controls.push_back(control);
00415 
00416         server->insert(int_marker);
00417         server->setCallback(int_marker.name, &processFeedback);
00418 }
00419 // %EndTag(ViewFacing)%
00420 
00421 
00422 // %Tag(Quadrocopter)%
00423 void makeQuadrocopterMarker( )
00424 {
00425         InteractiveMarker int_marker;
00426         int_marker.header.frame_id = "/base_link";
00427         int_marker.pose.position.y = -3.0 * marker_pos++;;
00428         int_marker.scale = 1;
00429 
00430         int_marker.name = "quadrocopter";
00431         int_marker.description = "Quadrocopter";
00432 
00433         makeBoxControl(int_marker);
00434 
00435         InteractiveMarkerControl control;
00436 
00437         control.orientation.w = 1;
00438         control.orientation.x = 0;
00439         control.orientation.y = 1;
00440         control.orientation.z = 0;
00441         control.interaction_mode = InteractiveMarkerControl::MOVE_ROTATE;
00442         int_marker.controls.push_back(control);
00443         control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS;
00444         int_marker.controls.push_back(control);
00445 
00446         server->insert(int_marker);
00447         server->setCallback(int_marker.name, &processFeedback);
00448 }
00449 // %EndTag(Quadrocopter)%
00450 
00451 // %Tag(ChessPiece)%
00452 void makeChessPieceMarker( )
00453 {
00454         InteractiveMarker int_marker;
00455         int_marker.header.frame_id = "/base_link";
00456         int_marker.pose.position.y = -3.0 * marker_pos++;;
00457         int_marker.scale = 1;
00458 
00459         int_marker.name = "chess_piece";
00460         int_marker.description = "Chess Piece\n(2D Move + Alignment)";
00461 
00462         InteractiveMarkerControl control;
00463 
00464         control.orientation.w = 1;
00465         control.orientation.x = 0;
00466         control.orientation.y = 1;
00467         control.orientation.z = 0;
00468         control.interaction_mode = InteractiveMarkerControl::MOVE_PLANE;
00469         int_marker.controls.push_back(control);
00470 
00471         // make a box which also moves in the plane
00472         control.markers.push_back( makeBox(int_marker) );
00473         control.always_visible = true;
00474         int_marker.controls.push_back(control);
00475 
00476         // we want to use our special callback function
00477         server->insert(int_marker);
00478         server->setCallback(int_marker.name, &processFeedback);
00479 
00480         // set different callback for POSE_UPDATE feedback
00481         server->setCallback(int_marker.name, &alignMarker, visualization_msgs::InteractiveMarkerFeedback::POSE_UPDATE );
00482 }
00483 // %EndTag(ChessPiece)%
00484 
00485 // %Tag(PanTilt)%
00486 void makePanTiltMarker( )
00487 {
00488         InteractiveMarker int_marker;
00489         int_marker.header.frame_id = "/atc/laser/roof_rotating/base";
00490         //int_marker.header.frame_id = "/atc/vehicle/center_bumper";
00491         int_marker.pose.position.x = 0;
00492         int_marker.pose.position.y = 0;
00493         int_marker.pose.position.z = 0; int_marker.scale = 0.4;
00494 
00495         int_marker.name = "shaft";
00496         int_marker.description = " Laser3D control";
00497 
00498         //makeBoxControl(int_marker);
00499 
00500         InteractiveMarkerControl control;
00501 
00502         control.orientation.w = 1;
00503         control.orientation.x = 1;
00504         control.orientation.y = 0;
00505         control.orientation.z = 0;
00506         control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00507         control.orientation_mode = InteractiveMarkerControl::FIXED;
00508         int_marker.controls.push_back(control);
00509 
00510         server->insert(int_marker);
00511         server->setCallback(int_marker.name, &processFeedback);
00512 }
00513 // %EndTag(PanTilt)%
00514 
00515 // %Tag(Menu)%
00516 void makeMenuMarker()
00517 {
00518         InteractiveMarker int_marker;
00519         int_marker.header.frame_id = "/atc/laser/roof_rotating/base";
00520         //int_marker.header.frame_id = "/atc/vehicle/center_bumper";
00521         int_marker.pose.position.x = 0;
00522         int_marker.pose.position.y = 0;
00523         int_marker.pose.position.z = 0;
00524         int_marker.scale = 0.4;
00525 
00526         int_marker.name = "context_menu";
00527         int_marker.description = "Context Menu\n(Right Click)";
00528 
00529         InteractiveMarkerControl control;
00530 
00531         // make one control using default visuals
00532         control.interaction_mode = InteractiveMarkerControl::MENU;
00533         control.description="Options";
00534         control.name = "menu_only_control";
00535         int_marker.controls.push_back(control);
00536 
00537         // make one control showing a box
00538         //Marker marker = makeBox( int_marker );
00539         //control.markers.push_back( marker );
00540         control.always_visible = true;
00541         int_marker.controls.push_back(control);
00542 
00543         server->insert(int_marker);
00544         server->setCallback(int_marker.name, &processFeedback);
00545 //      setCallback (const std::string &name, FeedbackCallback feedback_cb, uint8_t feedback_type=DEFAULT_FEEDBACK_CB)
00546         
00547         menu_handler.apply( *server, int_marker.name );
00548 }
00549 // %EndTag(Menu)%
00550 
00551 // %Tag(Moving)%
00552 void makeMovingMarker()
00553 {
00554         InteractiveMarker int_marker;
00555         int_marker.header.frame_id = "/moving_frame";
00556         int_marker.pose.position.y = -3.0 * marker_pos++;;
00557         int_marker.scale = 1;
00558 
00559         int_marker.name = "moving";
00560         int_marker.description = "Marker Attached to a\nMoving Frame";
00561 
00562         InteractiveMarkerControl control;
00563 
00564         control.orientation.w = 1;
00565         control.orientation.x = 1;
00566         control.orientation.y = 0;
00567         control.orientation.z = 0;
00568         control.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS;
00569         int_marker.controls.push_back(control);
00570 
00571         control.interaction_mode = InteractiveMarkerControl::MOVE_PLANE;
00572         control.always_visible = true;
00573         control.markers.push_back( makeBox(int_marker) );
00574         int_marker.controls.push_back(control);
00575 
00576         server->insert(int_marker);
00577         server->setCallback(int_marker.name, &processFeedback);
00578 }
00579 // %EndTag(Moving)%
00580 
00581 // %Tag(main)%
00582 int main(int argc, char** argv)
00583 {
00584         ros::init(argc, argv, "laser3d_interactive_control_node");
00585         ros::NodeHandle n;
00586 
00587         //declare the publisher
00588         pub = n.advertise<sensor_msgs::JointState>("cmd", 1);
00589 
00590 
00591         // create a timer to update the published transforms
00592         //ros::Timer frame_timer = n.createTimer(ros::Duration(0.01), frameCallback);
00593 
00594         server.reset( new interactive_markers::InteractiveMarkerServer("imarker","",false) );
00595 
00596         ros::Duration(0.1).sleep();
00597 
00598 
00599         menu_handler.insert( "Position control", &processFeedback );
00600         interactive_markers::MenuHandler::EntryHandle sub_menu_handle = menu_handler.insert( "Speed control" );
00601         menu_handler.insert( sub_menu_handle, "30 RPM", &processFeedback );
00602         menu_handler.insert( sub_menu_handle, "60 RPM", &processFeedback );
00603 
00604         //make6DofMarker( false );
00605         //make6DofMarker( true );
00606         //makeRandomDofMarker( );
00607         //makeViewFacingMarker( );
00608         //makeQuadrocopterMarker( );
00609         //makeChessPieceMarker( );
00610         makePanTiltMarker( );
00611         makeMenuMarker( );
00612         //makeMovingMarker( );
00613 
00614         server->applyChanges();
00615 
00616         ros::spin();
00617 
00618         server.reset();
00619 }
00620 // %EndTag(main)%
00621 
00622 
00623 


laser_rotate_3d
Author(s): Ricardo Pascoal
autogenerated on Thu Nov 20 2014 11:35:41