16 #ifndef NAV2_ROS_COMMON__VALIDATE_MESSAGES_HPP_
17 #define NAV2_ROS_COMMON__VALIDATE_MESSAGES_HPP_
24 #include "nav_msgs/msg/occupancy_grid.hpp"
25 #include "nav_msgs/msg/odometry.hpp"
26 #include "nav2_msgs/msg/costmap.hpp"
27 #include "nav2_msgs/msg/costmap_meta_data.hpp"
28 #include "geometry_msgs/msg/pose_with_covariance_stamped.hpp"
29 #include "map_msgs/msg/occupancy_grid_update.hpp"
30 #include "sensor_msgs/msg/range.hpp"
53 bool validateMsg(
const double & num)
60 if (std::isinf(num)) {
return false;}
61 if (std::isnan(num)) {
return false;}
65 const double MAX_COVARIANCE = 1e9;
66 const double MIN_COVARIANCE = 0;
67 const double MIN_MAP_RESOLUTION = 1e-6;
68 const double MAX_RANGE_FIELD_OF_VIEW = M_PI;
71 bool validateMsg(
const std::array<double, N> & msg)
77 for (
const auto & element : msg) {
78 if (!validateMsg(element)) {
return false;}
80 if (std::abs(element) > MAX_COVARIANCE || element < MIN_COVARIANCE) {
88 constexpr
int NANOSECONDS_PER_SECOND = 1e9;
89 bool validateMsg(
const builtin_interfaces::msg::Time & msg)
91 if (msg.nanosec >= NANOSECONDS_PER_SECOND) {
97 bool validateMsg(
const std_msgs::msg::Header & msg)
100 if (!validateMsg(msg.stamp)) {
return false;}
107 if (msg.frame_id.empty()) {
return false;}
111 bool validateMsg(
const geometry_msgs::msg::Point & msg)
114 if (!validateMsg(msg.x)) {
return false;}
115 if (!validateMsg(msg.y)) {
return false;}
116 if (!validateMsg(msg.z)) {
return false;}
120 const double epsilon = 1e-4;
121 bool validateMsg(
const geometry_msgs::msg::Quaternion & msg)
124 if (!validateMsg(msg.x)) {
return false;}
125 if (!validateMsg(msg.y)) {
return false;}
126 if (!validateMsg(msg.z)) {
return false;}
127 if (!validateMsg(msg.w)) {
return false;}
129 if (abs(msg.x * msg.x + msg.y * msg.y + msg.z * msg.z + msg.w * msg.w - 1.0) >= epsilon) {
136 bool validateMsg(
const geometry_msgs::msg::Pose & msg)
139 if (!validateMsg(msg.position)) {
return false;}
140 if (!validateMsg(msg.orientation)) {
return false;}
144 bool validateMsg(
const geometry_msgs::msg::PoseWithCovariance & msg)
147 if (!validateMsg(msg.pose)) {
return false;}
148 if (!validateMsg(msg.covariance)) {
return false;}
153 bool validateMsg(
const geometry_msgs::msg::PoseWithCovarianceStamped & msg)
156 if (!validateMsg(msg.header)) {
return false;}
157 if (!validateMsg(msg.pose)) {
return false;}
158 if (!validateMsg(msg.pose.covariance)) {
return false;}
164 bool validateMsg(
const nav_msgs::msg::MapMetaData & msg)
167 if (!validateMsg(msg.origin)) {
return false;}
168 if (!validateMsg(msg.resolution)) {
return false;}
170 if (msg.resolution < MIN_MAP_RESOLUTION) {
return false;}
174 if (msg.height == 0 || msg.width == 0) {
return false;}
179 bool validateMsg(
const nav_msgs::msg::OccupancyGrid & msg)
182 if (!validateMsg(msg.header)) {
return false;}
184 if (!validateMsg(msg.info)) {
return false;}
186 if (msg.info.width > INT16_MAX || msg.info.height > INT16_MAX) {
192 if (msg.info.width != 0 &&
193 msg.info.height > std::numeric_limits<uint32_t>::max() / msg.info.width)
198 const uint32_t num_cells = msg.info.width * msg.info.height;
201 if (msg.data.size() !=
static_cast<size_t>(num_cells)) {
209 bool validateMsg(
const map_msgs::msg::OccupancyGridUpdate & msg)
212 if (!validateMsg(msg.header)) {
return false;}
215 if (msg.data.size() !=
static_cast<size_t>(msg.width) * msg.height) {
220 if (msg.x < 0 || msg.y < 0) {
return false;}
222 if (msg.x > INT16_MAX || msg.y > INT16_MAX ||
223 msg.width > INT16_MAX || msg.height > INT16_MAX)
229 if (msg.width != 0 &&
230 msg.height > std::numeric_limits<uint32_t>::max() / msg.width)
239 bool validateMsg(
const sensor_msgs::msg::Range & msg)
241 if (!validateMsg(msg.header)) {
return false;}
242 if (!validateMsg(
static_cast<double>(msg.field_of_view))) {
return false;}
243 if (!validateMsg(
static_cast<double>(msg.min_range))) {
return false;}
244 if (!validateMsg(
static_cast<double>(msg.max_range))) {
return false;}
245 if (!validateMsg(
static_cast<double>(msg.range))) {
return false;}
247 if (msg.field_of_view <= 0.0 || msg.field_of_view > MAX_RANGE_FIELD_OF_VIEW) {
251 if (msg.min_range < 0.0 || msg.max_range <= msg.min_range) {
258 bool validateMsg(
const nav2_msgs::msg::CostmapMetaData & msg)
260 if (!validateMsg(msg.origin)) {
return false;}
261 if (!validateMsg(msg.resolution)) {
return false;}
263 if (msg.resolution < MIN_MAP_RESOLUTION) {
return false;}
264 if (msg.size_x == 0 || msg.size_y == 0) {
return false;}
269 bool validateMsg(
const nav2_msgs::msg::Costmap & msg)
271 if (!validateMsg(msg.header)) {
return false;}
272 if (!validateMsg(msg.metadata)) {
return false;}
274 if (msg.metadata.size_x != 0 &&
275 msg.metadata.size_y > std::numeric_limits<uint32_t>::max() / msg.metadata.size_x)
279 const uint32_t num_cells = msg.metadata.size_x * msg.metadata.size_y;
281 if (msg.data.size() !=
static_cast<size_t>(num_cells)) {