41 RCLCPP_ERROR(
getLogger(),
"CbWaitForHeadingStable: no CpVehicleLocalPosition");
48 "CbWaitForHeadingStable: waiting for the heading to hold within %.2f deg/s over %.0f s%s "
51 checkExpected ?
" and match the parked heading" :
"",
params_.
timeoutS);
53 using clock = std::chrono::steady_clock;
54 const auto start = clock::now();
55 std::deque<std::pair<double, float>> samples;
56 rclcpp::Rate rate(10.0);
57 double lastReport = -10.0;
61 const double t = std::chrono::duration<double>(clock::now() - start).count();
66 while (!samples.empty() && t - samples.front().first >
params_.
windowS)
72 !samples.empty() && samples.back().first - samples.front().first >= 0.9 *
params_.
windowS;
73 float drift = 0.0f, offset = 0.0f;
74 bool stable =
false, aligned =
true;
78 float lo = 0.0f, hi = 0.0f;
79 for (
const auto & s : samples)
81 const float d =
wrapPi(s.second - samples.front().second);
94 if (windowFull && stable && aligned)
98 "CbWaitForHeadingStable: heading %.1f deg stable (%.2f deg over %.0f s%s) - posting "
100 samples.back().second * 180.0 / M_PI, drift * 180.0 / M_PI,
params_.
windowS,
101 checkExpected ? (
", offset " + std::to_string(offset * 180.0 / M_PI) +
" deg").c_str()
107 if (t - lastReport >= 2.0)
113 getLogger(),
"CbWaitForHeadingStable: collecting (%zu samples, position valid=%d)",
120 "CbWaitForHeadingStable: heading %.1f deg NOT ready: drift %.2f deg/s%s - the EKF "
121 "yaw is not trustworthy for takeoff",
122 samples.back().second * 180.0 / M_PI, drift /
params_.
windowS * 180.0 / M_PI,
124 ? (
", offset from parked heading " + std::to_string(offset * 180.0 / M_PI) +
" deg")
134 "CbWaitForHeadingStable: timeout (%.0f s): heading %.1f deg, drift %.2f deg/s. "
135 "Refusing to arm; restart the estimator / SITL",
136 params_.
timeoutS, samples.empty() ? 0.0 : samples.back().second * 180.0 / M_PI,
143 RCLCPP_WARN(
getLogger(),
"CbWaitForHeadingStable: shutdown requested");