16 #ifndef NAV2_ROS_COMMON__VALIDATE_MESSAGES_HPP_
17 #define NAV2_ROS_COMMON__VALIDATE_MESSAGES_HPP_
23 #include "nav_msgs/msg/occupancy_grid.hpp"
24 #include "nav_msgs/msg/odometry.hpp"
25 #include "geometry_msgs/msg/pose_with_covariance_stamped.hpp"
26 #include "map_msgs/msg/occupancy_grid_update.hpp"
27 #include "sensor_msgs/msg/range.hpp"
50 bool validateMsg(
const double & num)
57 if (std::isinf(num)) {
return false;}
58 if (std::isnan(num)) {
return false;}
62 const double MAX_COVARIANCE = 1e9;
63 const double MIN_COVARIANCE = 0;
64 const double MIN_MAP_RESOLUTION = 1e-6;
65 const double MAX_RANGE_FIELD_OF_VIEW = M_PI;
68 bool validateMsg(
const std::array<double, N> & msg)
74 for (
const auto & element : msg) {
75 if (!validateMsg(element)) {
return false;}
77 if (std::abs(element) > MAX_COVARIANCE || element < MIN_COVARIANCE) {
85 const int NSEC_PER_SEC = 1e9;
86 bool validateMsg(
const builtin_interfaces::msg::Time & msg)
88 if (msg.nanosec >= NSEC_PER_SEC) {
94 bool validateMsg(
const std_msgs::msg::Header & msg)
97 if (!validateMsg(msg.stamp)) {
return false;}
104 if (msg.frame_id.empty()) {
return false;}
108 bool validateMsg(
const geometry_msgs::msg::Point & msg)
111 if (!validateMsg(msg.x)) {
return false;}
112 if (!validateMsg(msg.y)) {
return false;}
113 if (!validateMsg(msg.z)) {
return false;}
117 const double epsilon = 1e-4;
118 bool validateMsg(
const geometry_msgs::msg::Quaternion & msg)
121 if (!validateMsg(msg.x)) {
return false;}
122 if (!validateMsg(msg.y)) {
return false;}
123 if (!validateMsg(msg.z)) {
return false;}
124 if (!validateMsg(msg.w)) {
return false;}
126 if (abs(msg.x * msg.x + msg.y * msg.y + msg.z * msg.z + msg.w * msg.w - 1.0) >= epsilon) {
133 bool validateMsg(
const geometry_msgs::msg::Pose & msg)
136 if (!validateMsg(msg.position)) {
return false;}
137 if (!validateMsg(msg.orientation)) {
return false;}
141 bool validateMsg(
const geometry_msgs::msg::PoseWithCovariance & msg)
144 if (!validateMsg(msg.pose)) {
return false;}
145 if (!validateMsg(msg.covariance)) {
return false;}
150 bool validateMsg(
const geometry_msgs::msg::PoseWithCovarianceStamped & msg)
153 if (!validateMsg(msg.header)) {
return false;}
154 if (!validateMsg(msg.pose)) {
return false;}
155 if (!validateMsg(msg.pose.covariance)) {
return false;}
161 bool validateMsg(
const nav_msgs::msg::MapMetaData & msg)
164 if (!validateMsg(msg.origin)) {
return false;}
165 if (!validateMsg(msg.resolution)) {
return false;}
167 if (msg.resolution < MIN_MAP_RESOLUTION) {
return false;}
171 if (msg.height == 0 || msg.width == 0) {
return false;}
176 bool validateMsg(
const nav_msgs::msg::OccupancyGrid & msg)
179 if (!validateMsg(msg.header)) {
return false;}
181 if (!validateMsg(msg.info)) {
return false;}
183 if (msg.info.width > INT16_MAX || msg.info.height > INT16_MAX) {
190 if (__builtin_mul_overflow(msg.info.width, msg.info.height, &num_cells)) {
196 if (msg.data.size() !=
static_cast<size_t>(num_cells)) {
204 bool validateMsg(
const map_msgs::msg::OccupancyGridUpdate & msg)
207 if (!validateMsg(msg.header)) {
return false;}
210 if (msg.data.size() !=
static_cast<size_t>(msg.width) * msg.height) {
215 if (msg.x < 0 || msg.y < 0) {
return false;}
217 if (msg.x > INT16_MAX || msg.y > INT16_MAX ||
218 msg.width > INT16_MAX || msg.height > INT16_MAX)
225 if (__builtin_mul_overflow(msg.width, msg.height, &num_cells)) {
233 bool validateMsg(
const sensor_msgs::msg::Range & msg)
235 if (!validateMsg(msg.header)) {
return false;}
236 if (!validateMsg(
static_cast<double>(msg.field_of_view))) {
return false;}
237 if (!validateMsg(
static_cast<double>(msg.min_range))) {
return false;}
238 if (!validateMsg(
static_cast<double>(msg.max_range))) {
return false;}
239 if (!validateMsg(
static_cast<double>(msg.range))) {
return false;}
241 if (msg.field_of_view <= 0.0 || msg.field_of_view > MAX_RANGE_FIELD_OF_VIEW) {
245 if (msg.min_range < 0.0 || msg.max_range <= msg.min_range) {