system_viewer.cpp
Go to the documentation of this file.
00001 
00009 #include <opencv2/core/core.hpp>
00010 #include <aruco/aruco.h>
00011 
00012 #include <ros/ros.h>
00013 #include <tf/transform_broadcaster.h>
00014 #include <visualization_msgs/Marker.h>
00015 
00016 #define VISUAL_MARKER_SIZE      0.08
00017 
00018 enum position_t
00019 {
00020         FIXED,
00021         RELATIVE,
00022         FLOATING,
00023 
00024         POSITION_NR_ITEMS
00025 };
00026 
00027 struct board_t
00028 {
00029         int uid;
00030         std::string name;
00031         position_t type;
00032 
00033         std::string relativeName;
00034         tf::Transform transform;
00035 };
00036 
00037 struct relative_board_t
00038 {
00039         board_t board;
00040         std::map<std::string, tf::Transform> transforms_map;
00041 };
00042 
00043 struct camera_t
00044 {
00045         int uid;
00046         std::string name;
00047         position_t type;
00048 
00049         tf::Transform transform;
00050 };
00051 
00052 class ArSysViewer
00053 {
00054         private:
00055                 std::string map_path;
00056                 std::map<std::string, board_t> boards_map;
00057                 std::map<std::string, relative_board_t> relativeBoards_map;
00058                 std::map<std::string, camera_t> cameras_map;
00059                 double digital_filter_change_rate;
00060 
00061                 ros::Subscriber transform_sub;
00062                 ros::Publisher rviz_marker_pub;
00063                 tf::TransformBroadcaster broadcaster;
00064                 ros::NodeHandle nh;
00065 
00066         public:
00067                 ArSysViewer()
00068                         : nh("~")
00069                 {
00070                         transform_sub = nh.subscribe ("/transform", 1, &ArSysViewer::transform_callback, this);
00071 
00072                         rviz_marker_pub = nh.advertise <visualization_msgs::Marker> ("visualization_marker", 0);
00073 
00074                         nh.param<std::string>("map_path", map_path, "map.yml");
00075                         nh.param<double>("digital_filter_change_rate", digital_filter_change_rate, 0.5);
00076 
00077                         readFromFile(map_path.c_str());
00078                         ROS_INFO("ArSys node started with boards map: %s", map_path.c_str());
00079                 }
00080 
00081                 void readFromFile ( string sfile ) throw ( cv::Exception )
00082                 {
00083                         try
00084                         {
00085                                 cv::FileStorage fs ( sfile,cv::FileStorage::READ );
00086                                 readFromFile ( fs );
00087                         }
00088                         catch (std::exception &ex)
00089                         {
00090                                 throw   cv::Exception ( 81818,"ArSysViewer::readFromFile",ex.what()+string(" file=)")+sfile ,__FILE__,__LINE__ );
00091                         }
00092                 }
00093 
00094 
00095                 void readFromFile ( cv::FileStorage &fs ) throw ( cv::Exception )
00096                 {
00097                         //look for the ar_map_boards and ar_map_cameras
00098                         if (fs["ar_map_boards"].name() != "ar_map_boards" || fs["ar_map_cameras"].name() != "ar_map_cameras")
00099                                 throw cv::Exception ( 81818,"ArSysViewer::readFromFile","invalid file type" ,__FILE__,__LINE__ );
00100 
00101                         cv::FileNode FnBoards=fs["ar_map_boards"];
00102                         for (cv::FileNodeIterator it = FnBoards.begin(); it != FnBoards.end(); ++it)
00103                         {
00104                                 board_t board;
00105 
00106                                 board.uid = boards_map.size();
00107                                 board.name = (std::string)(*it)["name"];
00108                                 if ((std::string)(*it)["type"] == "fixed")
00109                                 {
00110                                         board.type = FIXED;
00111 
00112                                 }
00113                                 else if ((std::string)(*it)["type"] == "relative")
00114                                 {
00115                                         board.type = RELATIVE;
00116                                         board.relativeName = (std::string)(*it)["relativeName"];
00117                                 }
00118                                 else
00119                                 {
00120                                         if ((std::string)(*it)["type"] != "floating") ROS_WARN("Unknow board type: %s for board %s, assuming floating",
00121                                                 ((std::string)(*it)["type"]).c_str(),
00122                                                 board.name.c_str());
00123                                         board.type = FLOATING;
00124                                         board.transform = tf::Transform::getIdentity(); //Initial position
00125                                 }
00126                                 if (board.type == FIXED || board.type == RELATIVE)
00127                                 {
00128                                         vector<float> coordinates3d;
00129                                         cv::FileNode FnPose = (*it)["pose"];
00130                                         cv::FileNodeIterator itc = FnPose.begin();
00131 
00132                                         (*itc)>>coordinates3d;
00133                                         if (coordinates3d.size() != 3)
00134                                                 throw cv::Exception ( 81818,"ArSysViewer::readFromFile","invalid file type 3" ,__FILE__,__LINE__ );
00135                                         tf::Vector3 ref_origin(coordinates3d[0], coordinates3d[1], coordinates3d[2]);
00136 
00137                                         (*++itc)>>coordinates3d;
00138                                         if (coordinates3d.size() != 3)
00139                                                 throw cv::Exception ( 81818,"ArSysViewer::readFromFile","invalid file type 3" ,__FILE__,__LINE__ );
00140                                         tf::Quaternion ref_rotation = tf::createQuaternionFromRPY(coordinates3d[0], coordinates3d[1], coordinates3d[2]);
00141 
00142                                         board.transform = tf::Transform(ref_rotation, ref_origin);
00143 
00144                                         if (board.type == RELATIVE)
00145                                         {
00146                                                 if (relativeBoards_map.count(board.relativeName) == 0)
00147                                                 {
00148                                                         relative_board_t relativeBoard;
00149 
00150                                                         relativeBoard.board.uid = relativeBoards_map.size();
00151                                                         relativeBoard.board.name = board.relativeName;
00152                                                         relativeBoard.board.type = FLOATING;
00153                                                         relativeBoard.board.transform = tf::Transform::getIdentity(); //Initial position
00154 
00155                                                         relativeBoards_map.insert(std::make_pair(relativeBoard.board.name, relativeBoard));
00156                                                 }
00157                                                 relativeBoards_map[board.relativeName].transforms_map.insert(std::make_pair(board.name, board.transform));
00158                                                 board.transform = tf::Transform::getIdentity(); //Done with relative, Initial position
00159                                         }
00160                                 }
00161 
00162                                 boards_map.insert(std::make_pair(board.name, board));
00163                         }
00164 
00165                         cv::FileNode FnCameras=fs["ar_map_cameras"];
00166                         for (cv::FileNodeIterator it = FnCameras.begin(); it != FnCameras.end(); ++it)
00167                         {
00168                                 camera_t camera;
00169 
00170                                 camera.uid = cameras_map.size();
00171                                 camera.name = (std::string)(*it)["name"];
00172                                 if ((std::string)(*it)["type"] == "fixed")
00173                                 {
00174                                         camera.type = FIXED;
00175 
00176                                         vector<float> coordinates3d;
00177                                         cv::FileNode FnPose = (*it)["pose"];
00178                                         cv::FileNodeIterator itc = FnPose.begin();
00179 
00180                                         (*itc)>>coordinates3d;
00181                                         if (coordinates3d.size() != 3)
00182                                                 throw cv::Exception ( 81818,"ArSysViewer::readFromFile","invalid file type 3" ,__FILE__,__LINE__ );
00183                                         tf::Vector3 ref_origin(coordinates3d[0], coordinates3d[1], coordinates3d[2]);
00184 
00185                                         (*++itc)>>coordinates3d;
00186                                         if (coordinates3d.size() != 3)
00187                                                 throw cv::Exception ( 81818,"ArSysViewer::readFromFile","invalid file type 3" ,__FILE__,__LINE__ );
00188                                         tf::Quaternion ref_rotation = tf::createQuaternionFromRPY(coordinates3d[0], coordinates3d[1], coordinates3d[2]);
00189 
00190                                         camera.transform = tf::Transform(ref_rotation, ref_origin);
00191                                 }
00192                                 else
00193                                 {
00194                                         if ((std::string)(*it)["type"] != "floating") ROS_WARN("Unknow camera type: %s for camera %s, assuming floating",
00195                                                 ((std::string)(*it)["type"]).c_str(),
00196                                                 camera.name.c_str());
00197                                         camera.type = FLOATING;
00198                                         camera.transform = tf::Transform::getIdentity(); //Initial position
00199                                 }
00200 
00201                                 cameras_map.insert(std::make_pair(camera.name, camera));
00202                         }
00203                 }
00204 
00205                 tf::Transform& digital_filter(tf::Transform &dst, const tf::Transform &src)
00206                 {
00207                         //dst = src;
00208 
00209                         tf::Vector3 posOld = dst.getOrigin();
00210                         tf::Vector3 posNew = src.getOrigin();
00211                         tf::Vector3 pos
00212                         (
00213                                 (1 - digital_filter_change_rate) * posOld.x() + digital_filter_change_rate * posNew.x(),
00214                                 (1 - digital_filter_change_rate) * posOld.y() + digital_filter_change_rate * posNew.y(),
00215                                 (1 - digital_filter_change_rate) * posOld.z() + digital_filter_change_rate * posNew.z()
00216                         );
00217                         dst.setOrigin(pos);
00218 
00219                         tf::Quaternion ornOld = dst.getRotation();
00220                         tf::Quaternion ornNew = src.getRotation();
00221                         tf::Quaternion orn
00222                         (
00223                                 (1 - digital_filter_change_rate) * ornOld.x() + digital_filter_change_rate * ornNew.x(),
00224                                 (1 - digital_filter_change_rate) * ornOld.y() + digital_filter_change_rate * ornNew.y(),
00225                                 (1 - digital_filter_change_rate) * ornOld.z() + digital_filter_change_rate * ornNew.z(),
00226                                 (1 - digital_filter_change_rate) * ornOld.w() + digital_filter_change_rate * ornNew.w()
00227                         );
00228                         dst.setRotation(orn);
00229 
00230                         return dst;
00231                 }
00232 
00233                 void transform_callback (const geometry_msgs::TransformStamped& transformMsg)
00234                 {
00235                         if (cameras_map.count(transformMsg.header.frame_id) == 0)
00236                         {
00237                                 ROS_WARN("Map file does not contain an entry for the '%s' camera! Adding as floating", transformMsg.header.frame_id.c_str());
00238 
00239                                 camera_t camera;
00240                                 camera.uid = cameras_map.size();
00241                                 camera.name = transformMsg.header.frame_id;
00242                                 camera.type = FLOATING;
00243                                 camera.transform = tf::Transform::getIdentity(); //Initial position
00244                                 cameras_map.insert(std::make_pair(camera.name, camera));
00245                         }
00246                         if (boards_map.count(transformMsg.child_frame_id) == 0)
00247                         {
00248                                 ROS_WARN("Map file does not contain an entry for the '%s' board! Adding as floating", transformMsg.child_frame_id.c_str());
00249 
00250                                 board_t board;
00251                                 board.uid = boards_map.size();
00252                                 board.name = transformMsg.child_frame_id;
00253                                 board.type = FLOATING;
00254                                 board.transform = tf::Transform::getIdentity(); //Initial position
00255                                 boards_map.insert(std::make_pair(board.name, board));
00256                         }
00257 
00258                         tf::StampedTransform stampedTransform;
00259                         tf::transformStampedMsgToTF(transformMsg, stampedTransform);
00260                         if (cameras_map[transformMsg.header.frame_id].type == FLOATING && boards_map[transformMsg.child_frame_id].type == FIXED)
00261                         {
00262                                 digital_filter(cameras_map[transformMsg.header.frame_id].transform, boards_map[transformMsg.child_frame_id].transform * stampedTransform.inverse());
00263                         }
00264                         tf::StampedTransform camStampedTransform (cameras_map[transformMsg.header.frame_id].transform, transformMsg.header.stamp, "world", transformMsg.header.frame_id);
00265                         broadcaster.sendTransform(camStampedTransform);
00266 
00267                         stampedTransform.setData(boards_map[transformMsg.child_frame_id].type == FIXED ?
00268                                 boards_map[transformMsg.child_frame_id].transform :
00269                                 digital_filter(boards_map[transformMsg.child_frame_id].transform, cameras_map[transformMsg.header.frame_id].transform * stampedTransform));
00270                         stampedTransform.frame_id_ = camStampedTransform.frame_id_;
00271                         broadcaster.sendTransform(stampedTransform);
00272                         if (boards_map[transformMsg.child_frame_id].type == RELATIVE)
00273                         {
00274                                 std::string relativeName = boards_map[transformMsg.child_frame_id].relativeName;
00275 
00276                                 digital_filter(relativeBoards_map[relativeName].board.transform, boards_map[transformMsg.child_frame_id].transform * relativeBoards_map[relativeName].transforms_map[transformMsg.child_frame_id]);
00277                                 tf::StampedTransform relativeStampedTransform(relativeBoards_map[relativeName].board.transform, transformMsg.header.stamp, "world", relativeName);
00278                                 broadcaster.sendTransform(relativeStampedTransform);
00279                         }
00280 
00281                         //Generate visual marker
00282                         tf::Vector3 markerOrigin (0, 0, 0.1 * VISUAL_MARKER_SIZE);
00283                         tf::Transform m (tf::Quaternion::getIdentity(), markerOrigin);
00284                         tf::Transform markerPose = boards_map[transformMsg.child_frame_id].transform * m;
00285 
00286                         visualization_msgs::Marker visualMarker;
00287                         tf::poseTFToMsg (markerPose, visualMarker.pose);
00288 
00289                         visualMarker.header.frame_id = stampedTransform.frame_id_;
00290                         visualMarker.header.stamp = transformMsg.header.stamp;
00291                         visualMarker.id = boards_map[transformMsg.child_frame_id].uid;
00292 
00293                         visualMarker.scale.x = 1.0 * VISUAL_MARKER_SIZE;
00294                         visualMarker.scale.y = 1.0 * VISUAL_MARKER_SIZE;
00295                         visualMarker.scale.z = 0.1 * VISUAL_MARKER_SIZE;
00296                         visualMarker.ns = "basic_shapes";
00297                         visualMarker.type = visualization_msgs::Marker::CUBE;
00298                         visualMarker.action = visualization_msgs::Marker::ADD;
00299                         visualMarker.color.r = (float)visualMarker.id / (boards_map.size() - 1);
00300                         visualMarker.color.g = 1.0 - visualMarker.color.r;
00301                         visualMarker.color.b = (float)boards_map[transformMsg.child_frame_id].type / (POSITION_NR_ITEMS - 1);
00302                         visualMarker.color.a = 1.0;
00303                         visualMarker.lifetime = ros::Duration (1.0);
00304                         //Publish visual marker
00305                         rviz_marker_pub.publish(visualMarker);
00306                 }
00307 };
00308 
00309 
00310 int main(int argc,char **argv)
00311 {
00312         ros::init(argc, argv, "ar_system_viewer");
00313 
00314         ArSysViewer node;
00315 
00316         ros::spin();
00317 }


ar_sys
Author(s): Hamdi Sahloul , Rafael Muñoz Salinas , Bence Magyar
autogenerated on Sun Oct 5 2014 22:12:49