sick_cloud_transform.h
Go to the documentation of this file.
1 #include "sick_scan/sick_scan_base.h" /* Base definitions included in all header files, added by add_sick_scan_base_header.py. Do not edit this line. */
2 /*
3 * Copyright (C) 2017, Ing.-Buero Dr. Michael Lehning, Hildesheim
4 * Copyright (C) 2017, SICK AG, Waldkirch
5 * All rights reserved.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 *
25 * * Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * * Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * * Neither the name of Osnabrueck University nor the names of its
31 * contributors may be used to endorse or promote products derived from
32 * this software without specific prior written permission.
33 * * Neither the name of SICK AG nor the names of its
34 * contributors may be used to endorse or promote products derived from
35 * this software without specific prior written permission
36 * * Neither the name of Ing.-Buero Dr. Michael Lehning nor the names of its
37 * contributors may be used to endorse or promote products derived from
38 * this software without specific prior written permission
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
45 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
46 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
47 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
48 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
50 * POSSIBILITY OF SUCH DAMAGE.
51  *
52  * Created on: 12.08.2022
53  *
54  * Authors:
55  * Michael Lehning <michael.lehning@lehning.de>
56  *
57  * class SickCloudTransform applies an additional transform to the cartesian pointcloud, default: "0,0,0,0,0,0" (i.e. no transform)
58  * Note: add_transform_xyz_rpy is specified by 6D pose x,y,z,roll,pitch,yaw in [m] resp. [rad]
59  * It transforms a 3D point in cloud coordinates to 3D point in user defined world coordinates:
60  * add_transform_xyz_rpy := T[world,cloud] with parent "world" and child "cloud", i.e. P_world = T[world,cloud] * P_cloud
61  * The additional transform applies to cartesian lidar pointclouds and visualization marker (fields)
62  * It is NOT applied to polar pointclouds, radarscans, ldmrs objects or other messages
63  *
64  */
65 
66 #ifndef SICK_CLOUD_TRANSFORM_H_
67 #define SICK_CLOUD_TRANSFORM_H_
68 
69 #include <array>
70 #include <string>
71 #include <vector>
72 
74 
75 namespace sick_scan_xd
76 {
77  /*
78  * class SickCloudTransform applies an additional transform to the cartesian pointcloud, default: "0,0,0,0,0,0" (i.e. no transform)
79  * Note: add_transform_xyz_rpy is specified by 6D pose x,y,z,roll,pitch,yaw in [m] resp. [rad]
80  * It transforms a 3D point in cloud coordinates to 3D point in user defined world coordinates:
81  * add_transform_xyz_rpy := T[world,cloud] with parent "world" and child "cloud", i.e. P_world = T[world,cloud] * P_cloud
82  * The additional transform applies to cartesian lidar pointclouds and visualization marker (fields)
83  * It is NOT applied to polar pointclouds, radarscans, ldmrs objects or other messages
84  */
86  {
87  public:
88 
90  SickCloudTransform(rosNodePtr nh, bool cartesian_input_only /* = false */);
91  SickCloudTransform(rosNodePtr nh, const std::string& add_transform_xyz_rpy, bool cartesian_input_only /* = false */, bool add_transform_check_dynamic_updates /* = false */);
92 
93  /*
94  * Apply an optional transform to point (x, y, z).
95  * @param[in] float_type: float or double
96  * @param[in+out] x input x in child coordinates, output x in parent coordinates
97  * @param[in+out] y input y in child coordinates, output y in parent coordinates
98  * @param[in+out] z input z in child coordinates, output z in parent coordinates
99  */
100  template<typename float_type> inline void applyTransform(float_type& x, float_type& y, float_type& z)
101  {
102  // Check parameter and re-init if parameter "add_transform_xyz_rpy" changed
104  {
105  std::string add_transform_xyz_rpy = m_add_transform_xyz_rpy;
106  rosGetParam(m_nh, "add_transform_xyz_rpy", add_transform_xyz_rpy);
107  if (m_add_transform_xyz_rpy != add_transform_xyz_rpy)
108  {
110  {
111  ROS_ERROR_STREAM("## ERROR SickCloudTransform(): Re-Initialization by \"" << add_transform_xyz_rpy << "\" failed, use 6D pose \"x,y,z,roll,pitch,yaw\" in [m] resp. [rad]");
112  }
113  }
114  }
115  // Apply transform
117  {
118  float_type u = x * m_rotation_matrix[0][0] + y * m_rotation_matrix[0][1] + z * m_rotation_matrix[0][2];
119  float_type v = x * m_rotation_matrix[1][0] + y * m_rotation_matrix[1][1] + z * m_rotation_matrix[1][2];
120  float_type w = x * m_rotation_matrix[2][0] + y * m_rotation_matrix[2][1] + z * m_rotation_matrix[2][2];
121  x = u;
122  y = v;
123  z = w;
124  }
125  x += m_translation_vector[0];
126  y += m_translation_vector[1];
127  z += m_translation_vector[2];
128  }
129 
130  /*
131  * Return the azimuth offset, i.e. yaw in [rad] if only yaw is configured, or 0 otherwise (default)
132  */
133  inline float azimuthOffset(void) const
134  {
135  return m_azimuth_offset;
136  }
137 
138  protected:
139 
140  typedef std::array<float, 3> Vector3D; // 3D translation vector
141  typedef std::array<std::array<float, 3>, 3> Matrix3x3; // 3x3 rotation matrix
142 
143  // Initializes rotation matrix and translation vector from a 6D pose configuration (x,y,z,roll,pitch,yaw) in [m] resp. [rad]
144  bool init(const std::string& add_transform_xyz_rpy, bool cartesian_input_only, bool add_transform_check_dynamic_updates);
145 
146  // Converts roll (rotation about X), pitch (rotation about Y), yaw (rotation about Z) to 3x3 rotation matrix
147  static Matrix3x3 eulerToRot3x3(float roll, float pitch, float yaw);
148 
149  // Multiply two 3x3 matrices, return a * b
150  static Matrix3x3 multiply3x3(const Matrix3x3& a, const Matrix3x3& b);
151 
152  rosNodePtr m_nh = 0; // ros node handle
153  std::string m_add_transform_xyz_rpy = ""; // currently configured ros parameter "add_transform_xyz_rpy"
154  bool m_add_transform_check_dynamic_updates = false; // True: ros parameter "add_transform_xyz_rpy" can be updated during runtime by "rosparam set", False: parameter "add_transform_xyz_rpy" configured by launchfile only
155  bool m_cartesian_input_only = false; // currently configured parameter cartesian_input_only
156  bool m_apply_3x3_rotation = false; // true, if the 3x3 rotation_matrix has to be applied, otherwise false (default)
157  Vector3D m_translation_vector = { 0, 0, 0 }; // translational part x,y,z of the 6D pose, default: 0
158  Matrix3x3 m_rotation_matrix = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; // rotational part roll,pitch,yaw by 3x3 rotation matrix, default: 3x3 identity
159  float m_azimuth_offset = 0; // azimuth offset, i.e. yaw in [rad], if only yaw is configured (in this case an offset can be added to the lidar azimuth before conversion to cartesian pointcloud, which is faster than a 3x3 matrix multiplication)
160 
161  }; // class SickCloudTransform
162 } // namespace sick_scan_xd
163 #endif // SICK_CLOUD_TRANSFORM_H_
sick_scan_xd::SickCloudTransform::m_nh
rosNodePtr m_nh
Definition: sick_cloud_transform.h:152
sick_scan_xd::SickCloudTransform
Definition: sick_cloud_transform.h:85
sick_scan_xd::SickCloudTransform::SickCloudTransform
SickCloudTransform()
Definition: sick_cloud_transform.cpp:70
sick_scan_xd::SickCloudTransform::m_add_transform_check_dynamic_updates
bool m_add_transform_check_dynamic_updates
Definition: sick_cloud_transform.h:154
sick_scan_xd::SickCloudTransform::m_rotation_matrix
Matrix3x3 m_rotation_matrix
Definition: sick_cloud_transform.h:158
sick_scan_xd::SickCloudTransform::m_azimuth_offset
float m_azimuth_offset
Definition: sick_cloud_transform.h:159
sick_scan_xd
Definition: abstract_parser.cpp:65
sick_scan_xd::SickCloudTransform::m_apply_3x3_rotation
bool m_apply_3x3_rotation
Definition: sick_cloud_transform.h:156
sick_ros_wrapper.h
sick_scan_xd::SickCloudTransform::m_translation_vector
Vector3D m_translation_vector
Definition: sick_cloud_transform.h:157
sick_scan_xd::SickCloudTransform::m_cartesian_input_only
bool m_cartesian_input_only
Definition: sick_cloud_transform.h:155
sick_scan_xd::SickCloudTransform::Matrix3x3
std::array< std::array< float, 3 >, 3 > Matrix3x3
Definition: sick_cloud_transform.h:141
sick_scan_xd::SickCloudTransform::Vector3D
std::array< float, 3 > Vector3D
Definition: sick_cloud_transform.h:140
ros::NodeHandle
rosGetParam
bool rosGetParam(rosNodePtr nh, const std::string &param_name, T &param_value)
Definition: sick_ros_wrapper.h:167
sick_scan_xd::SickCloudTransform::eulerToRot3x3
static Matrix3x3 eulerToRot3x3(float roll, float pitch, float yaw)
Definition: sick_cloud_transform.cpp:156
sick_scan_xd::SickCloudTransform::m_add_transform_xyz_rpy
std::string m_add_transform_xyz_rpy
Definition: sick_cloud_transform.h:153
sick_scan_base.h
sick_scan_xd::SickCloudTransform::multiply3x3
static Matrix3x3 multiply3x3(const Matrix3x3 &a, const Matrix3x3 &b)
Definition: sick_cloud_transform.cpp:182
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(...)
Definition: sick_scan_ros2_example.cpp:72
sick_scan_xd::SickCloudTransform::applyTransform
void applyTransform(float_type &x, float_type &y, float_type &z)
Definition: sick_cloud_transform.h:100
sick_scan_xd::SickCloudTransform::azimuthOffset
float azimuthOffset(void) const
Definition: sick_cloud_transform.h:133
sick_scan_xd::SickCloudTransform::init
bool init(const std::string &add_transform_xyz_rpy, bool cartesian_input_only, bool add_transform_check_dynamic_updates)
Definition: sick_cloud_transform.cpp:99


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:10