pose_estimation_markermap_node.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, Lukas Pfeifhofer <lukas.pfeifhofer@devlabs.pro>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software without
17  * specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
33 
34 int main(int argc, char **argv) {
35  ros::init(argc, argv, "arPoseEstimation");
36 
37  /*
38  {
39  cv::Mat translation = cv::Mat::zeros(1, 3, CV_32FC1);
40  cv::Mat rotation = cv::Mat::zeros(1, 4, CV_32FC1);
41  rotation.at<float>(0, 0) = 1.0f;
42 
43  MarkerDetails markerTopLeft;
44  markerTopLeft.id = 85;
45  translation.at<float>(0, 0) = -0.036f;
46  translation.at<float>(0, 1) = 0.036f;
47  translation.copyTo(markerTopLeft.position);
48  rotation.copyTo(markerTopLeft.rotation);
49 
50  MarkerDetails markerTopRight;
51  markerTopRight.id = 166;
52  translation.at<float>(0, 0) = 0.036f;
53  translation.at<float>(0, 1) = 0.036f;
54  translation.copyTo(markerTopRight.position);
55  rotation.copyTo(markerTopRight.rotation);
56 
57  MarkerDetails markerBottomLeft;
58  markerBottomLeft.id = 161;
59  translation.at<float>(0, 0) = -0.036f;
60  translation.at<float>(0, 1) = -0.036f;
61  translation.copyTo(markerBottomLeft.position);
62  rotation.copyTo(markerBottomLeft.rotation);
63 
64  MarkerDetails markerBottomRight;
65  markerBottomRight.id = 227;
66  translation.at<float>(0, 0) = 0.036f;
67  translation.at<float>(0, 1) = -0.036f;
68  translation.copyTo(markerBottomRight.position);
69  rotation.copyTo(markerBottomRight.rotation);
70 
71  MarkerMapDetails markerMap;
72  markerMap.id = 1001;
73  markerMap.markers.push_back(markerTopLeft);
74  markerMap.markers.push_back(markerTopRight);
75  markerMap.markers.push_back(markerBottomLeft);
76  markerMap.markers.push_back(markerBottomRight);
77 
78  MarkerMapConfig markerMapConfig;
79  markerMapConfig.markerMaps.push_back(markerMap);
80 
81  cv::FileStorage fs("/home/privacy/Documents/ros/workspace_repo/test_marker_config.yml", cv::FileStorage::WRITE);
82  fs << "markerMapConfig" << markerMapConfig;
83  fs.release();
84  }
85  */
86 
87 
88  // Try to get config file path
89  std::string configPath;
90 
91  ros::NodeHandle pn("~");
92  if (!pn.getParam("marker_map_config", configPath)) {
93  ROS_ERROR("Parameter marker_map_config (Path to config file) is not provided. This node can not be started without a valid MarkerMap config.");
94  return EXIT_FAILURE;
95  }
96 
97  // Try to read config file
98  MarkerMapConfig markerMapConfig = MarkerMapConfig::readFromFile(configPath);
99  if (markerMapConfig.markerMaps.size() <= 0) {
100  ROS_ERROR("The provided MarkerMap config file (%s) is not existing, is invalid or contains not a single markerMap. This node can not be started without a valid MarkerMap config.", configPath.c_str());
101  return EXIT_FAILURE;
102  }
103 
104  ros::NodeHandle n;
105  PoseEstimationMarkerMapNode poseEstimationNode(n, markerMapConfig);
106  ros::spin();
107  return EXIT_SUCCESS;
108 }
109 
111  // Register dynamic_reconfigure callback
113  configServer_.setCallback(configCallbackFnct_);
114 
115  // Advert marker publisher
116  pub_markers_ = n_.advertise<marker_msgs::MarkerDetection>("markers", 10);
117 
118  // Subscribe to FiducialDetection.msg topic
120 }
121 
123 
124 void PoseEstimationMarkerMapNode::fiducialDetectionCallback(const marker_msgs::FiducialDetection::ConstPtr &msg) {
125 
126  // Convert camera matrix msg to cv::Mat
127  float camera_matrix_data[9];
128  for(int i = 0; i < 9; i++)
129  camera_matrix_data[i] = msg->camera_k[i];
130  cv::Mat camera_k = cv::Mat(3, 3, CV_32F, camera_matrix_data);
131 
132  float distortion_coefficients_data[5];
133  for(int i = 0; i < 5; i++)
134  distortion_coefficients_data[i] = msg->camera_d[i];
135  cv::Mat camera_d = cv::Mat(1, 5, CV_32F, distortion_coefficients_data);
136 
137 
138  std::vector<MarkerFiducials> markerFiducials;
139  for (auto &fiducial:msg->fiducial) {
140  MarkerFiducials marker(fiducial.ids, fiducial.ids_confidence);
141 
142  for (auto &object_point:fiducial.object_points)
143  marker.object_points.push_back(cv::Point3f(object_point.x, object_point.y, object_point.z));
144 
145  for (auto &image_point:fiducial.image_points)
146  marker.image_points.push_back(cv::Point2f(image_point.x, image_point.y));
147 
148  markerFiducials.push_back(marker);
149  }
150 
151  // Do pose estimation
152  std::vector<MarkerPose> markerPoses;
153  base_.estimatePose(markerFiducials, camera_k, camera_d, markerPoses);
154 
155  // Publish ros messages
156  publishMarkers(msg->header, markerPoses);
157 }
158 
159 static tf::StampedTransform markerPoseToStampedTransform(MarkerPose &markerPose, const std_msgs::Header &header) {
160  cv::Mat m = markerPose.rt_matrix;
161 
162  tf::Vector3 tv(
163  m.at<float>(0, 3),
164  m.at<float>(1, 3),
165  m.at<float>(2, 3)
166  );
167 
168  tf::Matrix3x3 rm(
169  m.at<float>(0, 0), m.at<float>(0, 1), m.at<float>(0, 2),
170  m.at<float>(1, 0), m.at<float>(1, 1), m.at<float>(1, 2),
171  m.at<float>(2, 0), m.at<float>(2, 1), m.at<float>(2, 2)
172  );
173 
174  char markerLabel[64];
175  if (markerPose.ids.size() > 0) {
176  sprintf(markerLabel, "t%i", markerPose.ids[0]);
177  } else {
178  sprintf(markerLabel, "t?");
179  }
180  return tf::StampedTransform(tf::Transform(rm, tv), ros::Time::now(), header.frame_id, markerLabel);
181 }
182 
183 void PoseEstimationMarkerMapNode::publishMarkers(const std_msgs::Header &header, std::vector<MarkerPose> &markerPoses) {
184  marker_msgs::MarkerDetection msg;
185 
186  msg.header = header;
187  msg.distance_min = 0; //TODO
188  msg.distance_max = 8; //TODO
189  msg.distance_max_id = 5; //TODO
190  msg.view_direction.x = 0; //TODO
191  msg.view_direction.y = 0; //TODO
192  msg.view_direction.z = 0; //TODO
193  msg.view_direction.w = 1; //TODO
194  msg.fov_horizontal = 6; //TODO
195  msg.fov_vertical = 0; //TODO
196 
197  msg.markers = marker_msgs::MarkerDetection::_markers_type();
198 
199  for (auto &markerPose:markerPoses) {
200  tf::StampedTransform stf = markerPoseToStampedTransform(markerPose, header);
201 
202  // Send transform
205 
206  // Push marker into MarkerDetection message
207  marker_msgs::Marker marker;
208 
209  marker.ids = markerPose.ids;
210  marker.ids_confidence = markerPose.ids_confidence;
211  tf::poseTFToMsg(stf, marker.pose);
212 
213  msg.markers.push_back(marker);
214  }
215 
216  // Publish MarkerDetection message
218  pub_markers_.publish(msg);
219 }
220 
221 void PoseEstimationMarkerMapNode::configCallback(tuw_marker_pose_estimation::MarkerPoseEstimationConfig &config, uint32_t level) {
222  base_.getParameters().setPoseEstimatorType(config.pose_estimation_type);
223  base_.getParameters().setPublishTf(config.publish_tf);
224  base_.getParameters().setPublishMarkers(config.publish_markers);
226 }
dynamic_reconfigure::Server< tuw_marker_pose_estimation::MarkerPoseEstimationConfig >::CallbackType configCallbackFnct_
void publish(const boost::shared_ptr< M > &message) const
std::vector< MarkerMapDetails > markerMaps
void fiducialDetectionCallback(const marker_msgs::FiducialDetection::ConstPtr &msg)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
PoseEstimationMarkerMapNode(ros::NodeHandle &n, MarkerMapConfig markerMapConfig)
cv::Mat rt_matrix
Definition: marker_pose.h:44
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void publishMarkers(const std_msgs::Header &header, std::vector< MarkerPose > &markerPoses)
void estimatePose(std::vector< MarkerFiducials > &markers, cv::Mat &camera_k, cv::Mat &camera_d, std::vector< MarkerPose > &markerPoses)
std::vector< int > ids
Definition: marker_pose.h:41
ROSCPP_DECL void spin(Spinner &spinner)
int main(int argc, char **argv)
static MarkerMapConfig readFromFile(std::string path)
void sendTransform(const StampedTransform &transform)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
PoseEstimationMarkerMapParameters & getParameters()
std::vector< cv::Point3f > object_points
static void poseTFToMsg(const Pose &bt, geometry_msgs::Pose &msg)
bool getParam(const std::string &key, std::string &s) const
static Time now()
std::vector< cv::Point2f > image_points
static tf::StampedTransform markerPoseToStampedTransform(MarkerPose &markerPose, const std_msgs::Header &header)
#define ROS_ERROR(...)
tf::TransformBroadcaster transformBroadcaster_
dynamic_reconfigure::Server< tuw_marker_pose_estimation::MarkerPoseEstimationConfig > configServer_
void configCallback(tuw_marker_pose_estimation::MarkerPoseEstimationConfig &config, uint32_t level)


tuw_marker_pose_estimation
Author(s): Lukas Pfeifhofer
autogenerated on Mon Jun 10 2019 15:42:13