aruco_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 
32 #include "tuw_aruco/aruco_node.h"
33 
34 int main(int argc, char **argv) {
35  ros::init(argc, argv, "arMarker");
37  ArUcoNode arUcoNode(n);
38  ros::spin();
39  return 0;
40 }
41 
42 ArUcoNode::ArUcoNode(ros::NodeHandle &n) : n_(n), imageTransport_(n) {
43 
44  // Register dynamic_reconfigure callback
45  configCallbackFnct_ = boost::bind(&ArUcoNode::configCallback, this , _1, _2);
47 
48  // Advert marker publisher
49  pub_markers_ = n_.advertise<marker_msgs::MarkerDetection>("markers", 10);
50 
51  // Advert fiducial publisher
52  pub_fiducials_ = n_.advertise<marker_msgs::FiducialDetection>("fiducials", 10);
53 
54  // Subscribe to image topic
56 
58  cv::namedWindow("aruco_node_debug", CV_WINDOW_NORMAL | CV_GUI_NORMAL);
59  }
60 
61 }
62 
64 
65 static aruco::CameraParameters cameraInfoToCameraParameters(const sensor_msgs::CameraInfoConstPtr &camer_info) {
66  float camera_matrix_data[9];
67  for(int i = 0; i < 9; i++)
68  camera_matrix_data[i] = camer_info->K[i];
69  cv::Mat camera_matrix = cv::Mat(3, 3, CV_32F, camera_matrix_data);
70 
71  float distortion_coefficients_data[5];
72  for(int i = 0; i < 5; i++)
73  distortion_coefficients_data[i] = camer_info->D[i];
74  cv::Mat distortion_coefficients = cv::Mat(1, 5, CV_32F, distortion_coefficients_data);
75 
76  return aruco::CameraParameters(camera_matrix, distortion_coefficients, cv::Size(camer_info->width, camer_info->height));
77 }
78 
79 static tf::StampedTransform markerPoseToStampedTransform(ArUcoMarkerPose &markerPose, const std_msgs::Header &header) {
80  cv::Mat m = markerPose.getRTMatrix();
81 
82  tf::Vector3 tv(
83  m.at<float>(0, 3),
84  m.at<float>(1, 3),
85  m.at<float>(2, 3)
86  );
87 
88  tf::Matrix3x3 rm(
89  m.at<float>(0, 0), m.at<float>(0, 1), m.at<float>(0, 2),
90  m.at<float>(1, 0), m.at<float>(1, 1), m.at<float>(1, 2),
91  m.at<float>(2, 0), m.at<float>(2, 1), m.at<float>(2, 2)
92  );
93 
94  char markerLabel[64];
95  sprintf(markerLabel, "t%i", markerPose.getMarkerId());
96  return tf::StampedTransform(tf::Transform(rm, tv), ros::Time::now(), header.frame_id, markerLabel);
97 }
98 
99 void ArUcoNode::publishMarkers(const std_msgs::Header &header, vector<ArUcoMarkerPose> &markerPoses) {
100  marker_msgs::MarkerDetection msg;
101 
102  msg.header = header;
103  msg.distance_min = 0; //TODO
104  msg.distance_max = 8; //TODO
105  msg.distance_max_id = 5; //TODO
106  msg.view_direction.x = 0; //TODO
107  msg.view_direction.y = 0; //TODO
108  msg.view_direction.z = 0; //TODO
109  msg.view_direction.w = 1; //TODO
110  msg.fov_horizontal = 6; //TODO
111  msg.fov_vertical = 0; //TODO
112 
113  msg.markers = marker_msgs::MarkerDetection::_markers_type();
114 
115  for (auto &markerPose:markerPoses) {
116  tf::StampedTransform stf = markerPoseToStampedTransform(markerPose, header);
117 
118  // Send transform
121 
122  // Push marker into MarkerDetection message
123  marker_msgs::Marker marker;
124 
125  marker.ids.resize(1);
126  marker.ids_confidence.resize(1);
127  marker.ids[0] = markerPose.getMarkerId();
128  marker.ids_confidence[0] = 1;
129  tf::poseTFToMsg(stf, marker.pose);
130 
131  msg.markers.push_back(marker);
132  }
133 
134  // Publish MarkerDetection message
136  pub_markers_.publish(msg);
137 }
138 
139 void ArUcoNode::publishFiducials(const std_msgs::Header &header, vector<aruco::Marker> &markers, const sensor_msgs::CameraInfoConstPtr &camer_info_) {
140  marker_msgs::FiducialDetection msg;
141  msg.header = header;
142  msg.camera_k = camer_info_->K;
143  msg.camera_d = camer_info_->D;
144 
145  for (auto &marker:markers) {
146  marker_msgs::Fiducial fiducial;
147 
148  // Add all object points
149  for (auto &cvp: marker.get3DPoints(base_.getParameters().getMarkerSize())) {
150  geometry_msgs::Point point;
151  point.x = cvp.x;
152  point.y = cvp.y;
153  point.z = cvp.z;
154  fiducial.object_points.push_back(point);
155  }
156 
157  // Add all images points
158  for (cv::Point2f &p2d: marker) {
159  geometry_msgs::Point point;
160  point.x = p2d.x;
161  point.y = p2d.y;
162  point.z = 0.0f; // imagePoints are 2d
163  fiducial.image_points.push_back(point);
164  }
165 
166  fiducial.ids.resize(1);
167  fiducial.ids_confidence.resize(1);
168  fiducial.ids[0] = marker.id;
169  fiducial.ids_confidence[0] = 1;
170 
171  msg.fiducial.push_back(fiducial);
172  }
173 
174  pub_fiducials_.publish(msg);
175 }
176 
177 void ArUcoNode::imageCallback(const sensor_msgs::ImageConstPtr &image_msg, const sensor_msgs::CameraInfoConstPtr &camer_info_) {
178  cv_bridge::CvImagePtr imgPtr;
179  try {
180  // Convert ros image message to cv::Mat
182 
183  // Convert ros camera parameter
184  aruco::CameraParameters camParams = cameraInfoToCameraParameters(camer_info_);
185 
186 
187  // Detect markers
188  vector<aruco::Marker> markers;
189  base_.detectMarkers(markers, imgPtr->image);
190 
191  // If enabled publish fiducials
193  publishFiducials(image_msg->header, markers, camer_info_);
194 
195  // If enabled do pose estimation for every marker found
197  vector<ArUcoMarkerPose> markerPoses;
198  base_.estimatePose(markerPoses, markers, camParams);
199 
200 
201  // Publish markers
202  publishMarkers(image_msg->header, markerPoses);
203  }
204 
205 
206  // Draw markers if debug image is enabled
208  cv::Mat debugImage;
209  cvtColor(imgPtr->image, debugImage, cv::COLOR_GRAY2BGR);
210 
211  for (unsigned int i = 0; i < markers.size(); i++) {
212  // draw 2d info
213  markers[i].draw(debugImage, cv::Scalar(0, 0, 255), 1);
214 
215  // draw a 3d cube
216  aruco::CvDrawingUtils::draw3dCube(debugImage, markers[i], camParams);
217  aruco::CvDrawingUtils::draw3dAxis(debugImage, markers[i], camParams);
218  }
219 
220  cv::imshow("aruco_node_debug", debugImage);
221  cv::waitKey(5);
222  }
223  } catch (cv_bridge::Exception &e) {
224  ROS_ERROR ("cv_bridge exception: %s", e.what());
225  return;
226  }
227 }
228 
229 void ArUcoNode::configCallback(tuw_aruco::ArUcoConfig &config, uint32_t level) {
230  base_.getParameters().setShowDebugImage(config.show_debug_image);
231  base_.getParameters().setDictionary(config.marker_dictonary);
232  base_.getParameters().setMarkerSize(config.marker_size);
233  base_.getParameters().setPublishTf(config.publish_tf);
234  base_.getParameters().setPublishMarkers(config.publish_markers);
235  base_.getParameters().setPublishFiducials(config.publish_fiducials);
236  base_.getParameters().setPoseEstimationEnabled(config.pose_estimation_enabled);
238 }
239 
void refreshParameters()
Definition: aruco_base.cpp:59
void setPublishFiducials(bool b)
static tf::StampedTransform markerPoseToStampedTransform(ArUcoMarkerPose &markerPose, const std_msgs::Header &header)
Definition: aruco_node.cpp:79
void publish(const boost::shared_ptr< M > &message) const
image_transport::ImageTransport imageTransport_
Definition: aruco_node.h:59
CameraSubscriber subscribeCamera(const std::string &base_topic, uint32_t queue_size, const CameraSubscriber::Callback &callback, const ros::VoidPtr &tracked_object=ros::VoidPtr(), const TransportHints &transport_hints=TransportHints())
image_transport::CameraSubscriber cameraSubscriber_
Definition: aruco_node.h:60
void publishMarkers(const std_msgs::Header &header, vector< ArUcoMarkerPose > &markerPoses)
Definition: aruco_node.cpp:99
bool getPoseEstimationEnabled()
ros::NodeHandle n_
Definition: aruco_node.h:57
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
static aruco::CameraParameters cameraInfoToCameraParameters(const sensor_msgs::CameraInfoConstPtr &camer_info)
Definition: aruco_node.cpp:65
static void draw3dAxis(cv::Mat &Image, const CameraParameters &CP, const cv::Mat &Rvec, const cv::Mat &Tvec, float axis_size)
ROSCPP_DECL void spin(Spinner &spinner)
tf::TransformBroadcaster transformBroadcaster_
Definition: aruco_node.h:62
void setPublishMarkers(bool b)
void imageCallback(const sensor_msgs::ImageConstPtr &image_msg, const sensor_msgs::CameraInfoConstPtr &camer_info_)
Definition: aruco_node.cpp:177
void setPoseEstimationEnabled(bool b)
void setShowDebugImage(bool b)
void configCallback(tuw_aruco::ArUcoConfig &config, uint32_t level)
Definition: aruco_node.cpp:229
ros::Publisher pub_fiducials_
Definition: aruco_node.h:64
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
void estimatePose(vector< ArUcoMarkerPose > &markerPoses, vector< aruco::Marker > &markers, aruco::CameraParameters cameraParams)
Definition: aruco_base.cpp:44
dynamic_reconfigure::Server< tuw_aruco::ArUcoConfig >::CallbackType configCallbackFnct_
Definition: aruco_node.h:67
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
void sendTransform(const StampedTransform &transform)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
Parameters of the camera.
static void draw3dCube(cv::Mat &Image, Marker &m, const CameraParameters &CP, bool setYperpendicular=false)
ArUcoBase base_
Definition: aruco_node.h:69
void setPublishTf(bool b)
int main(int argc, char **argv)
Definition: aruco_node.cpp:34
static void poseTFToMsg(const Pose &bt, geometry_msgs::Pose &msg)
void setDictionary(std::string dictionary)
static Time now()
ros::Publisher pub_markers_
Definition: aruco_node.h:63
void setMarkerSize(float mSize)
void detectMarkers(vector< aruco::Marker > &markers, cv::Mat image)
Definition: aruco_base.cpp:40
void publishFiducials(const std_msgs::Header &header, vector< aruco::Marker > &markers, const sensor_msgs::CameraInfoConstPtr &camer_info_)
Definition: aruco_node.cpp:139
#define ROS_ERROR(...)
ArUcoParameters & getParameters()
Definition: aruco_base.cpp:55
dynamic_reconfigure::Server< tuw_aruco::ArUcoConfig > configServer_
Definition: aruco_node.h:66
ArUcoNode(ros::NodeHandle &n)
Definition: aruco_node.cpp:42


tuw_aruco
Author(s): Lukas Pfeifhofer
autogenerated on Mon Jun 10 2019 15:40:45