82 const double w = msg->q[0], x = msg->q[1], y = msg->q[2], z = msg->q[3];
83 const double yaw = std::atan2(2.0 * (w * z + x * y), 1.0 - 2.0 * (y * y + z * z));
86 const double dt =
static_cast<double>(msg->timestamp -
lastYawStampUs_) * 1e-6;
88 d = std::atan2(std::sin(d), std::cos(d));
89 if (dt > 1e-4 && dt < 0.5)
91 const float rate =
static_cast<float>(d / dt);
99 attitudeQ_ = {msg->q[0], msg->q[1], msg->q[2], msg->q[3]};
105 std::array<float, 4> q;
116 const tf2::Quaternion kNedEnuQ(0.70710678118654752, 0.70710678118654752, 0.0, 0.0);
117 const tf2::Quaternion kFrdFluQ(1.0, 0.0, 0.0, 0.0);
118 const tf2::Quaternion qNedFrd(q[1], q[2], q[3], q[0]);
119 tf2::Quaternion qEnuFlu = kNedEnuQ * qNedFrd * kFrdFluQ;
121 const tf2::Matrix3x3 m(qEnuFlu);
122 const double yaw = std::atan2(m[1][0], m[0][0]);
123 tf2::Matrix3x3 unyaw;
124 unyaw.setRPY(0.0, 0.0, -yaw);
125 const tf2::Matrix3x3 level = unyaw * m;
126 for (
int i = 0; i < 3; ++i)
128 for (
int j = 0; j < 3; ++j)
130 r[i * 3 + j] =
static_cast<float>(level[i][j]);
144 getLogger(),
"CpForwardObstacleGuard: yawing at %.2f rad/s - cone gated",
yawRate_.load());
157 float minRange = std::numeric_limits<float>::infinity();
159 std::array<float, 9> r{};
162 sensor_msgs::PointCloud2ConstIterator<float> ix(msg,
"x");
163 sensor_msgs::PointCloud2ConstIterator<float> iy(msg,
"y");
164 sensor_msgs::PointCloud2ConstIterator<float> iz(msg,
"z");
165 for (; ix != ix.end(); ++ix, ++iy, ++iz)
170 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z))
176 const float lx = r[0] * x + r[1] * y + r[2] * z;
177 const float ly = r[3] * x + r[4] * y + r[5] * z;
178 const float lz = r[6] * x + r[7] * y + r[8] * z;
187 const float r = std::sqrt(x * x + y * y + z * z);
221 getLogger(),
"CpForwardObstacleGuard: OBSTACLE min range %.2f m (%d hits in cone)",
233 RCLCPP_INFO(
getLogger(),
"CpForwardObstacleGuard: cleared (min range %.2f m)", minRange);