interactive_ellipsoid.cpp
Go to the documentation of this file.
00001 #include <Eigen/Eigen>
00002 #include <boost/format.hpp>
00003 #include <boost/make_shared.hpp>
00004 #include <boost/foreach.hpp>
00005 
00006 #include <ros/ros.h>
00007 #include <rosbag/bag.h>
00008 #include <rosbag/view.h>
00009 #include <rosbag/message_instance.h>
00010 #include <interactive_markers/interactive_marker_server.h>
00011 #include <tf/transform_broadcaster.h>
00012 #include <geometry_msgs/Pose.h>
00013 #include <tf_conversions/tf_eigen.h>
00014 
00015 #include <hrl_ellipsoidal_control/EllipsoidParams.h>
00016 #include <hrl_ellipsoidal_control/LoadEllipsoidParams.h>
00017 //#include <hrl_ellipsoidal_control/utils.h>
00018 
00019 using namespace std;
00020 
00021 class InteractiveEllipse 
00022 {
00023 private:
00024     interactive_markers::InteractiveMarkerServer im_server_;
00025     tf::TransformBroadcaster tf_broad_;
00026     ros::Publisher params_pub;
00027     ros::Subscriber params_cmd;
00028     std::string parent_frame_, child_frame_;
00029     double rate_;
00030     ros::Timer tf_timer_;
00031     geometry_msgs::Pose marker_pose_;
00032     double z_axis_, y_axis_, old_z_axis_, old_y_axis_;
00033     geometry_msgs::Transform old_marker_tf_;
00034     geometry_msgs::TransformStamped tf_msg_;
00035     hrl_ellipsoidal_control::EllipsoidParams cur_e_params_;
00036     ros::ServiceServer load_param_srv_;
00037     bool is_oblate;
00038 public:
00039     InteractiveEllipse(const std::string& parent_frame, const std::string& child_frame, double rate = 100);
00040     void processTFControl(const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback);
00041     void processEllipseControlY(const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback);
00042     void processEllipseControlZ(const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback);
00043     void addTFMarker(const geometry_msgs::Transform& mkr_tf);
00044     void addEllipseMarker();
00045     void publishTF(const ros::TimerEvent& event);
00046     void loadEllipsoidParams(const hrl_ellipsoidal_control::EllipsoidParams& e_params);
00047     void bagTF(const string& bag_name);
00048     bool loadParamCB(hrl_ellipsoidal_control::LoadEllipsoidParams::Request& req,
00049                      hrl_ellipsoidal_control::LoadEllipsoidParams::Response& resp);
00050 };
00051 
00052 InteractiveEllipse::InteractiveEllipse(const std::string& parent_frame, 
00053                                        const std::string& child_frame, double rate) :
00054     im_server_("transform_marker"),
00055     parent_frame_(parent_frame),
00056     child_frame_(child_frame),
00057     rate_(rate), z_axis_(0.0), y_axis_(0.0) 
00058     {
00059     ros::NodeHandle nh;
00060     marker_pose_.orientation.w = 1;
00061     params_pub = nh.advertise<hrl_ellipsoidal_control::EllipsoidParams>("/ellipsoid_params", 1);
00062     params_cmd = nh.subscribe("/ell_params_cmd", 1, &InteractiveEllipse::loadEllipsoidParams, this);
00063     load_param_srv_ = nh.advertiseService("/load_ellipsoid_params", 
00064                                           &InteractiveEllipse::loadParamCB, this);
00065 }
00066 
00067 void InteractiveEllipse::addTFMarker(const geometry_msgs::Transform& mkr_tf) 
00068 {
00069     ros::NodeHandle nh;
00070     visualization_msgs::InteractiveMarker tf_marker;
00071     tf_marker.header.frame_id = parent_frame_;
00072     tf_marker.pose.position.x = mkr_tf.translation.x;
00073     tf_marker.pose.position.y = mkr_tf.translation.y;
00074     tf_marker.pose.position.z = mkr_tf.translation.z;
00075     tf_marker.pose.orientation.x = mkr_tf.rotation.x;
00076     tf_marker.pose.orientation.y = mkr_tf.rotation.y;
00077     tf_marker.pose.orientation.z = mkr_tf.rotation.z;
00078     tf_marker.pose.orientation.w = mkr_tf.rotation.w;
00079     tf_marker.name = "tf_marker";
00080     tf_marker.scale = 0.2;
00081     visualization_msgs::InteractiveMarkerControl tf_control;
00082     tf_control.orientation_mode = visualization_msgs::InteractiveMarkerControl::INHERIT;
00083     // x
00084     tf_control.orientation.x = 1; tf_control.orientation.y = 0;
00085     tf_control.orientation.z = 0; tf_control.orientation.w = 1;
00086     tf_control.name = "rotate_x";
00087     tf_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00088     tf_marker.controls.push_back(tf_control);
00089     tf_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00090     tf_marker.controls.push_back(tf_control);
00091     // y
00092     tf_control.orientation.x = 0; tf_control.orientation.y = 1;
00093     tf_control.orientation.z = 0; tf_control.orientation.w = 1;
00094     tf_control.name = "rotate_y";
00095     tf_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00096     tf_marker.controls.push_back(tf_control);
00097     tf_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00098     tf_marker.controls.push_back(tf_control);
00099     // z
00100     tf_control.orientation.x = 0; tf_control.orientation.y = 0;
00101     tf_control.orientation.z = 1; tf_control.orientation.w = 1;
00102     tf_control.name = "rotate_z";
00103     tf_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::ROTATE_AXIS;
00104     tf_marker.controls.push_back(tf_control);
00105     tf_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00106     tf_marker.controls.push_back(tf_control);
00107     im_server_.insert(tf_marker, boost::bind(&InteractiveEllipse::processTFControl, this, _1));
00108     im_server_.applyChanges();
00109     tf_timer_ = nh.createTimer(ros::Duration(1.0 / rate_), &InteractiveEllipse::publishTF, this);
00110 }
00111 
00112 void InteractiveEllipse::processTFControl(
00113         const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback) 
00114         {
00115     ROS_INFO_STREAM(tf_msg_.transform.translation.x << " " << 
00116                     tf_msg_.transform.translation.y << " " <<
00117                     tf_msg_.transform.translation.z << " " <<
00118                     tf_msg_.transform.rotation.x << " " <<
00119                     tf_msg_.transform.rotation.y << " " <<
00120                     tf_msg_.transform.rotation.z << " " <<
00121                     tf_msg_.transform.rotation.w);
00122     marker_pose_ = feedback->pose;
00123 }
00124 
00125 void InteractiveEllipse::addEllipseMarker() 
00126 {
00127     visualization_msgs::InteractiveMarker tf_marker;
00128     tf_marker.header.frame_id = child_frame_;
00129     tf_marker.name = "ellipse_marker_y";
00130     tf_marker.scale = 0.4;
00131     visualization_msgs::InteractiveMarkerControl tf_control;
00132     tf_control.orientation_mode = visualization_msgs::InteractiveMarkerControl::INHERIT;
00133     // y
00134     tf_control.orientation.x = 0; tf_control.orientation.y = 1;
00135     tf_control.orientation.z = 0; tf_control.orientation.w = 1;
00136     tf_control.name = "shift_y";
00137     tf_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00138     tf_marker.controls.push_back(tf_control);
00139     im_server_.insert(tf_marker, boost::bind(&InteractiveEllipse::processEllipseControlY, this, _1));
00140     tf_marker.controls.clear();
00141     // z
00142     tf_marker.name = "ellipse_marker_z";
00143     tf_control.orientation.x = 0; tf_control.orientation.y = 0;
00144     tf_control.orientation.z = 1; tf_control.orientation.w = 1;
00145     tf_control.name = "shift_z";
00146     tf_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::MOVE_AXIS;
00147     tf_marker.controls.push_back(tf_control);
00148     im_server_.insert(tf_marker, boost::bind(&InteractiveEllipse::processEllipseControlZ, this, _1));
00149     im_server_.applyChanges();
00150 }
00151 
00152 void InteractiveEllipse::processEllipseControlY(
00153         const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback) 
00154         {
00155     z_axis_ = feedback->pose.position.z;
00156 }
00157 
00158 void InteractiveEllipse::processEllipseControlZ(
00159         const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback) 
00160         {
00161     y_axis_ = feedback->pose.position.y;
00162 }
00163 
00164 void InteractiveEllipse::publishTF(const ros::TimerEvent& event) 
00165 {
00166     tf_msg_.header.stamp = ros::Time::now();
00167     tf_msg_.header.frame_id = parent_frame_;
00168     tf_msg_.child_frame_id = child_frame_;
00169     tf_msg_.transform.translation.x = marker_pose_.position.x;
00170     tf_msg_.transform.translation.y = marker_pose_.position.y;
00171     tf_msg_.transform.translation.z = marker_pose_.position.z;
00172     tf_msg_.transform.rotation.x = marker_pose_.orientation.x;
00173     tf_msg_.transform.rotation.y = marker_pose_.orientation.y;
00174     tf_msg_.transform.rotation.z = marker_pose_.orientation.z;
00175     tf_msg_.transform.rotation.w = marker_pose_.orientation.w;
00176     tf::Transform cur_tf, old_tf;
00177     tf::transformMsgToTF(tf_msg_.transform, cur_tf);
00178     tf::transformMsgToTF(old_marker_tf_, old_tf);
00179     Eigen::Affine3d cur_tf_eig, old_tf_eig;
00180     tf::TransformTFToEigen(cur_tf, cur_tf_eig);
00181     tf::TransformTFToEigen(old_tf, old_tf_eig);
00182     cur_tf_eig = cur_tf_eig;
00183     tf::TransformEigenToTF(cur_tf_eig, cur_tf);
00184     tf::transformTFToMsg(cur_tf, tf_msg_.transform);
00185     tf_broad_.sendTransform(tf_msg_);
00186     hrl_ellipsoidal_control::EllipsoidParams e_params;
00187     e_params.e_frame = tf_msg_;
00188     e_params.height = y_axis_ + old_y_axis_;
00189     e_params.E = z_axis_ + old_z_axis_;
00190     e_params.is_oblate = is_oblate;
00191     params_pub.publish(e_params);
00192     cur_e_params_ = e_params;
00193 }
00194 
00195 void InteractiveEllipse::loadEllipsoidParams(const hrl_ellipsoidal_control::EllipsoidParams& e_params) 
00196 {
00197     geometry_msgs::Pose pose, empty_pose;
00198     pose.position.x = e_params.e_frame.transform.translation.x;
00199     pose.position.y = e_params.e_frame.transform.translation.y;
00200     pose.position.z = e_params.e_frame.transform.translation.z;
00201     pose.orientation.x = e_params.e_frame.transform.rotation.x;
00202     pose.orientation.y = e_params.e_frame.transform.rotation.y;
00203     pose.orientation.z = e_params.e_frame.transform.rotation.z;
00204     pose.orientation.w = e_params.e_frame.transform.rotation.w;
00205     marker_pose_ = pose;
00206     empty_pose.orientation.w = 1;
00207     im_server_.setPose("tf_marker", pose);
00208     im_server_.setPose("ellipse_marker_y", empty_pose);
00209     im_server_.setPose("ellipse_marker_z", empty_pose);
00210     im_server_.applyChanges();
00211 
00212     old_y_axis_ = e_params.height;
00213     old_z_axis_ = e_params.E;
00214     is_oblate = e_params.is_oblate;
00215 }
00216 
00217 void InteractiveEllipse::bagTF(const string& bag_name) 
00218 {
00219     rosbag::Bag bag;
00220     bag.open(bag_name, rosbag::bagmode::Write);
00221     bag.write("/ellipsoid_params", ros::Time::now(), cur_e_params_);
00222     bag.close();
00223 }
00224 
00225 bool InteractiveEllipse::loadParamCB(hrl_ellipsoidal_control::LoadEllipsoidParams::Request& req,
00226                                      hrl_ellipsoidal_control::LoadEllipsoidParams::Response& resp)
00227 {
00228     loadEllipsoidParams(req.params);
00229     return true;
00230 }
00231 
00232 int main(int argc, char **argv)
00233 {
00234     ros::init(argc, argv, "interative_ellipse");
00235     if(argc < 3 || argc > 7) {
00236         printf("Usage: interative_ellipse parent_frame child_frame rate [inital_params] [save_params] [use_ellipsoid_markers]\n");
00237         return 1;
00238     }
00239     if(argc >= 4) {
00240         InteractiveEllipse itf(argv[1], argv[2], atof(argv[3]));
00241         geometry_msgs::Transform mkr_tf;
00242         mkr_tf.rotation.w = 1;
00243         itf.addTFMarker(mkr_tf);
00244         if(!(argc >= 7 && atoi(argv[6])))
00245             itf.addEllipseMarker();
00246         if(argc >= 5) {
00247             // load params
00248             hrl_ellipsoidal_control::EllipsoidParams::Ptr e_params;
00249             rosbag::Bag bag;
00250             bag.open(argv[4], rosbag::bagmode::Read);
00251             rosbag::View view(bag, rosbag::TopicQuery("/ellipsoid_params"));
00252             BOOST_FOREACH(rosbag::MessageInstance const msg, view) {
00253                 e_params = msg.instantiate< hrl_ellipsoidal_control::EllipsoidParams >();
00254                 break;
00255             }
00256             bag.close();
00257             itf.loadEllipsoidParams(*e_params);
00258         }
00259         ros::spin();
00260         if(argc >= 6)
00261             itf.bagTF(argv[5]);
00262     } 
00263 
00264     return 0;
00265 }


hrl_ellipsoidal_control
Author(s): Kelsey Hawkins
autogenerated on Wed Nov 27 2013 11:41:49