103 std::array<float, 9> r{};
107 std::array<float, 4> q;
119 std::vector<float> leftY, rightY, floorZ, ceilZ;
126 sensor_msgs::PointCloud2ConstIterator<float> ix(msg,
"x");
127 sensor_msgs::PointCloud2ConstIterator<float> iy(msg,
"y");
128 sensor_msgs::PointCloud2ConstIterator<float> iz(msg,
"z");
129 for (; ix != ix.end(); ++ix, ++iy, ++iz)
134 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z))
138 if (x * x + y * y + z * z < minRangeSq)
144 const float lx = r[0] * x + r[1] * y + r[2] * z;
145 const float ly = r[3] * x + r[4] * y + r[5] * z;
146 const float lz = r[6] * x + r[7] * y + r[8] * z;
167 rightY.push_back(-y);
180 floorZ.push_back(-z);
192 const float left = kthSmallest(leftY, kw);
193 const float right = kthSmallest(rightY, kw);
194 const float floorD = kthSmallest(floorZ, kf);
195 const float ceilD = kthSmallest(ceilZ, kf);
198 float lateral = 0.0f;
199 if (std::isfinite(left) && std::isfinite(right))
201 lateral = 0.5f * (left - right);
202 const float nearer = std::min(left, right);
215 float vertical = 0.0f;
216 if (std::isfinite(floorD))
220 if (std::isfinite(ceilD))
224 if (std::isfinite(floorD))
242 const auto now = std::chrono::steady_clock::now();
243 if (std::chrono::duration<double>(now -
lastLog_).count() >= 2.0)
248 "CpTunnelCentering: walls L %.1f R %.1f, floor %.1f, ceiling %.1f m -> lateral %+.2f, "