├── launch
└── point_cloud_converter.launch
├── package.xml
├── CMakeLists.txt
└── src
└── converter.cpp
/launch/point_cloud_converter.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | point_cloud_converter
4 | 0.0.0
5 | The point_cloud_converter package to convert PointCloud to PointCloud2 or PointCloud2 to PointCloud. Basically the node of
6 | http://wiki.ros.org/point_cloud_converter by Radu Bogdan Rusu revived.
7 |
8 |
9 |
10 |
11 | Sammy Pfeiffer
12 |
13 |
14 | TODO
15 |
16 | catkin
17 | roscpp
18 | sensor_msgs
19 | roscpp
20 | sensor_msgs
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(point_cloud_converter)
3 |
4 | ## Find catkin macros and libraries
5 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
6 | ## is used, also find other catkin packages
7 | find_package(catkin REQUIRED COMPONENTS
8 | roscpp
9 | sensor_msgs
10 | )
11 |
12 |
13 |
14 | catkin_package()
15 |
16 | ###########
17 | ## Build ##
18 | ###########
19 |
20 | ## Specify additional locations of header files
21 | ## Your package locations should be listed before other locations
22 | # include_directories(include)
23 | include_directories(
24 | ${catkin_INCLUDE_DIRS}
25 | )
26 |
27 | ## Declare a cpp library
28 | # add_library(point_cloud_converter
29 | # src/${PROJECT_NAME}/point_cloud_converter.cpp
30 | # )
31 |
32 | ## Declare a cpp executable
33 | add_executable(point_cloud_converter_node src/converter.cpp)
34 |
35 | ## Add cmake target dependencies of the executable/library
36 | ## as an example, message headers may need to be generated before nodes
37 | # add_dependencies(point_cloud_converter_node point_cloud_converter_generate_messages_cpp)
38 |
39 | ## Specify libraries to link a library or executable target against
40 | target_link_libraries(point_cloud_converter_node
41 | ${catkin_LIBRARIES}
42 | )
43 |
44 | #############
45 | ## Install ##
46 | #############
47 |
48 | # all install targets should use catkin DESTINATION variables
49 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
50 |
51 | ## Mark executable scripts (Python etc.) for installation
52 | ## in contrast to setup.py, you can choose the destination
53 | # install(PROGRAMS
54 | # scripts/my_python_script
55 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
56 | # )
57 |
58 | ## Mark executables and/or libraries for installation
59 | install(TARGETS point_cloud_converter_node
60 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
61 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
62 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
63 | )
64 |
65 |
66 | foreach(dir launch)
67 | install(DIRECTORY ${dir}/
68 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/${dir})
69 | endforeach(dir)
70 |
71 |
72 | ## Mark cpp header files for installation
73 | # install(DIRECTORY include/${PROJECT_NAME}/
74 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
75 | # FILES_MATCHING PATTERN "*.h"
76 | # PATTERN ".svn" EXCLUDE
77 | # )
78 |
79 | ## Mark other files for installation (e.g. launch and bag files, etc.)
80 | # install(FILES
81 | # # myfile1
82 | # # myfile2
83 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
84 | # )
85 |
86 | #############
87 | ## Testing ##
88 | #############
89 |
90 | ## Add gtest based cpp test target and link libraries
91 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_point_cloud_converter.cpp)
92 | # if(TARGET ${PROJECT_NAME}-test)
93 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
94 | # endif()
95 |
96 | ## Add folders to be run by python nosetests
97 | # catkin_add_nosetests(test)
98 |
--------------------------------------------------------------------------------
/src/converter.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Software License Agreement (BSD License)
3 | *
4 | * Copyright (c) 2009, Willow Garage, Inc.
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions
9 | * are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright
12 | * notice, this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above
14 | * copyright notice, this list of conditions and the following
15 | * disclaimer in the documentation and/or other materials provided
16 | * with the distribution.
17 | * * Neither the name of Willow Garage, Inc. nor the names of its
18 | * contributors may be used to endorse or promote products derived
19 | * from this software without specific prior written permission.
20 | *
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 | * POSSIBILITY OF SUCH DAMAGE.
33 | *
34 | * $Id: converter.cpp 33249 2010-03-11 02:09:24Z rusu $
35 | *
36 | */
37 |
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 |
44 | using namespace std;
45 |
46 | class PointCloudConverter
47 | {
48 | private:
49 | boost::mutex m_mutex_;
50 | // ROS
51 | ros::NodeHandle nh_;
52 | ros::Subscriber sub_points_, sub_points2_;
53 | ros::Publisher pub_points_, pub_points2_;
54 |
55 | int queue_size_;
56 | string points_in_, points2_in_, points_out_, points2_out_;
57 |
58 | public:
59 | PointCloudConverter () : nh_ ("~"), queue_size_ (100),
60 | points_in_ ("/points_in"), points2_in_ ("/points2_in"),
61 | points_out_ ("/points_out"), points2_out_ ("/points2_out")
62 | {
63 | // Subscribe to the cloud topic using both the old message format and the new
64 | sub_points_ = nh_.subscribe (points_in_, queue_size_, &PointCloudConverter::cloud_cb_points, this);
65 | sub_points2_ = nh_.subscribe (points2_in_, queue_size_, &PointCloudConverter::cloud_cb_points2, this);
66 | pub_points_ = nh_.advertise (points_out_, queue_size_);
67 | pub_points2_ = nh_.advertise (points2_out_, queue_size_);
68 | ROS_INFO ("PointCloudConverter initialized to transform from PointCloud (%s) to PointCloud2 (%s).", nh_.resolveName (points_in_).c_str (), nh_.resolveName (points2_out_).c_str ());
69 | ROS_INFO ("PointCloudConverter initialized to transform from PointCloud2 (%s) to PointCloud (%s).", nh_.resolveName (points2_in_).c_str (), nh_.resolveName (points_out_).c_str ());
70 | }
71 |
72 |
73 | inline std::string
74 | getFieldsList (const sensor_msgs::PointCloud2 &cloud)
75 | {
76 | std::string result;
77 | for (size_t i = 0; i < cloud.fields.size () - 1; ++i)
78 | result += cloud.fields[i].name + " ";
79 | result += cloud.fields[cloud.fields.size () - 1].name;
80 | return (result);
81 | }
82 |
83 |
84 | inline std::string
85 | getFieldsList (const sensor_msgs::PointCloud &points)
86 | {
87 | std::string result = "x y z";
88 | for (size_t i = 0; i < points.channels.size (); i++)
89 | result = result + " " + points.channels[i].name;
90 | return (result);
91 | }
92 |
93 |
94 | void
95 | cloud_cb_points2 (const sensor_msgs::PointCloud2ConstPtr &msg)
96 | {
97 | if (pub_points_.getNumSubscribers () <= 0)
98 | {
99 | //ROS_DEBUG ("[point_cloud_converter] Got a PointCloud2 with %d points on %s, but no subscribers.", msg->width * msg->height, nh_.resolveName (points2_in_).c_str ());
100 | return;
101 | }
102 |
103 | ROS_DEBUG ("[point_cloud_converter] Got a PointCloud2 with %d points (%s) on %s.", msg->width * msg->height, getFieldsList (*msg).c_str (), nh_.resolveName (points2_in_).c_str ());
104 |
105 | sensor_msgs::PointCloud output;
106 | // Convert to the new PointCloud format
107 | if (!sensor_msgs::convertPointCloud2ToPointCloud (*msg, output))
108 | {
109 | ROS_ERROR ("[point_cloud_converter] Conversion from sensor_msgs::PointCloud2 to sensor_msgs::PointCloud failed!");
110 | return;
111 | }
112 | ROS_DEBUG ("[point_cloud_converter] Publishing a PointCloud with %d points on %s.", (int)output.points.size (), nh_.resolveName (points_out_).c_str ());
113 | pub_points_.publish (output);
114 | }
115 |
116 |
117 | void
118 | cloud_cb_points (const sensor_msgs::PointCloudConstPtr &msg)
119 | {
120 | if (pub_points2_.getNumSubscribers () <= 0)
121 | {
122 | //ROS_DEBUG ("[point_cloud_converter] Got a PointCloud with %d points on %s, but no subscribers.", (int)msg->points.size (), nh_.resolveName (points_in_).c_str ());
123 | return;
124 | }
125 |
126 | ROS_DEBUG ("[point_cloud_converter] Got a PointCloud with %d points (%s) on %s.", (int)msg->points.size (), getFieldsList (*msg).c_str (), nh_.resolveName (points_in_).c_str ());
127 |
128 | sensor_msgs::PointCloud2 output;
129 | // Convert to the old point cloud format
130 | if (!sensor_msgs::convertPointCloudToPointCloud2 (*msg, output))
131 | {
132 | ROS_ERROR ("[point_cloud_converter] Conversion from sensor_msgs::PointCloud to sensor_msgs::PointCloud2 failed!");
133 | return;
134 | }
135 | ROS_DEBUG ("[point_cloud_converter] Publishing a PointCloud2 with %d points on %s.", output.height * output.width, nh_.resolveName (points2_out_).c_str ());
136 | pub_points2_.publish (output);
137 | }
138 |
139 | };
140 |
141 | /* ---[ */
142 | int
143 | main (int argc, char** argv)
144 | {
145 | // ROS init
146 | ros::init (argc, argv, "point_cloud_converter", ros::init_options::AnonymousName);
147 |
148 | PointCloudConverter p;
149 | ros::spin ();
150 |
151 | return (0);
152 | }
--------------------------------------------------------------------------------