SMACC2
Loading...
Searching...
No Matches
cl_px4_mr::CbWaitForHeadingStable Class Reference

#include <cb_wait_for_heading_stable.hpp>

Inheritance diagram for cl_px4_mr::CbWaitForHeadingStable:
Inheritance graph
Collaboration diagram for cl_px4_mr::CbWaitForHeadingStable:
Collaboration graph

Public Member Functions

 CbWaitForHeadingStable (HeadingStableParams params={})
 
void onEntry () override
 
void onExit () override
 
- Public Member Functions inherited from cl_px4_mr::CbPx4ClientBehaviorBase
template<typename TOrthogonal , typename TSourceObject >
void onStateOrthogonalAllocation ()
 
virtual ~CbPx4ClientBehaviorBase ()
 
void setTimeout (std::chrono::milliseconds timeout)
 
bool hasTimeout () const
 
void update () override
 
- Public Member Functions inherited from smacc2::SmaccAsyncClientBehavior
template<typename TOrthogonal , typename TSourceObject >
void onStateOrthogonalAllocation ()
 
virtual ~SmaccAsyncClientBehavior ()
 
template<typename TCallback , typename T >
smacc2::SmaccSignalConnection onSuccess (TCallback callback, T *object)
 
template<typename TCallback , typename T >
smacc2::SmaccSignalConnection onFinished (TCallback callback, T *object)
 
template<typename TCallback , typename T >
smacc2::SmaccSignalConnection onFailure (TCallback callback, T *object)
 
void requestForceFinish ()
 
void executeOnEntry () override
 
void executeOnExit () override
 
void waitOnEntryThread (bool requestFinish)
 
template<typename TCallbackMethod , typename T >
smacc2::SmaccSignalConnection onSuccess (TCallbackMethod callback, T *object)
 
template<typename TCallbackMethod , typename T >
smacc2::SmaccSignalConnection onFinished (TCallbackMethod callback, T *object)
 
template<typename TCallbackMethod , typename T >
smacc2::SmaccSignalConnection onFailure (TCallbackMethod callback, T *object)
 
- Public Member Functions inherited from smacc2::ISmaccClientBehavior
 ISmaccClientBehavior ()
 
virtual ~ISmaccClientBehavior ()
 
ISmaccStateMachine * getStateMachine ()
 
std::string getName () const
 
template<typename SmaccClientType >
void requiresClient (SmaccClientType *&storage)
 
template<typename SmaccComponentType >
void requiresComponent (SmaccComponentType *&storage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
template<typename SmaccComponentType >
void requiresComponent (std::string name, SmaccComponentType *&storage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
- Public Member Functions inherited from smacc2::ISmaccUpdatable
 ISmaccUpdatable ()
 
 ISmaccUpdatable (rclcpp::Duration duration)
 
void executeUpdate (rclcpp::Node::SharedPtr node)
 
void setUpdatePeriod (rclcpp::Duration duration)
 

Private Attributes

HeadingStableParams params_
 

Additional Inherited Members

- Protected Member Functions inherited from cl_px4_mr::CbPx4ClientBehaviorBase
virtual void wireCompletionSignals ()
 
void postPx4Success ()
 
void postPx4Failure ()
 
- Protected Member Functions inherited from smacc2::SmaccAsyncClientBehavior
void postSuccessEvent ()
 
void postFailureEvent ()
 
virtual void dispose () override
 
bool isShutdownRequested ()
 onEntry is executed in a new thread. However the current state cannot be left until the onEntry thread finishes. This flag can be checked from the onEntry thread to force finishing the thread.
 
- Protected Member Functions inherited from smacc2::ISmaccClientBehavior
virtual void runtimeConfigure ()
 
template<typename EventType >
void postEvent (const EventType &ev)
 
template<typename EventType >
void postEvent ()
 
ISmaccState * getCurrentState ()
 
virtual rclcpp::Node::SharedPtr getNode () const
 
virtual rclcpp::Logger getLogger () const
 
- Protected Member Functions inherited from smacc2::ISmaccUpdatable
- Protected Attributes inherited from cl_px4_mr::CbPx4ClientBehaviorBase
CpVehicleCommand * vehicleCommand_ = nullptr
 
CpVehicleStatus * vehicleStatus_ = nullptr
 
CpTrajectorySetpoint * trajectorySetpoint_ = nullptr
 
CpGoalChecker * goalChecker_ = nullptr
 
CpVehicleLocalPosition * localPosition_ = nullptr
 
CpOffboardKeepAlive * offboardKeepAlive_ = nullptr
 

Detailed Description

Definition at line 47 of file cb_wait_for_heading_stable.hpp.

Constructor & Destructor Documentation

◆ CbWaitForHeadingStable()

cl_px4_mr::CbWaitForHeadingStable::CbWaitForHeadingStable ( HeadingStableParams params = {})
explicit

Definition at line 35 of file cb_wait_for_heading_stable.cpp.

35: params_(params) {}

Member Function Documentation

◆ onEntry()

void cl_px4_mr::CbWaitForHeadingStable::onEntry ( )
overridevirtual

Reimplemented from smacc2::ISmaccClientBehavior.

Definition at line 37 of file cb_wait_for_heading_stable.cpp.

38{
39 if (localPosition_ == nullptr)
40 {
41 RCLCPP_ERROR(getLogger(), "CbWaitForHeadingStable: no CpVehicleLocalPosition");
42 this->postPx4Failure();
43 return;
44 }
45 const bool checkExpected = std::isfinite(params_.expectedHeadingRad);
46 RCLCPP_INFO(
47 getLogger(),
48 "CbWaitForHeadingStable: waiting for the heading to hold within %.2f deg/s over %.0f s%s "
49 "(timeout %.0f s)",
50 params_.maxDriftRadS * 180.0 / M_PI, params_.windowS,
51 checkExpected ? " and match the parked heading" : "", params_.timeoutS);
52
53 using clock = std::chrono::steady_clock;
54 const auto start = clock::now();
55 std::deque<std::pair<double, float>> samples; // (t since start, heading)
56 rclcpp::Rate rate(10.0);
57 double lastReport = -10.0;
58
59 while (!this->isShutdownRequested())
60 {
61 const double t = std::chrono::duration<double>(clock::now() - start).count();
63 {
64 samples.emplace_back(t, localPosition_->getHeading());
65 }
66 while (!samples.empty() && t - samples.front().first > params_.windowS)
67 {
68 samples.pop_front();
69 }
70
71 bool windowFull =
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;
75 if (windowFull)
76 {
77 // unwrap over the window: max excursion from the first sample
78 float lo = 0.0f, hi = 0.0f;
79 for (const auto & s : samples)
80 {
81 const float d = wrapPi(s.second - samples.front().second);
82 lo = std::min(lo, d);
83 hi = std::max(hi, d);
84 }
85 drift = hi - lo;
86 stable = drift <= static_cast<float>(params_.maxDriftRadS * params_.windowS);
87 if (checkExpected)
88 {
89 offset = wrapPi(samples.back().second - params_.expectedHeadingRad);
90 aligned = std::fabs(offset) <= params_.headingTolRad;
91 }
92 }
93
94 if (windowFull && stable && aligned)
95 {
96 RCLCPP_INFO(
97 getLogger(),
98 "CbWaitForHeadingStable: heading %.1f deg stable (%.2f deg over %.0f s%s) - posting "
99 "success",
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()
102 : "");
103 this->postPx4Success();
104 return;
105 }
106
107 if (t - lastReport >= 2.0)
108 {
109 lastReport = t;
110 if (!windowFull)
111 {
112 RCLCPP_INFO(
113 getLogger(), "CbWaitForHeadingStable: collecting (%zu samples, position valid=%d)",
114 samples.size(), static_cast<int>(localPosition_->isValid()));
115 }
116 else
117 {
118 RCLCPP_WARN(
119 getLogger(),
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,
123 checkExpected
124 ? (", offset from parked heading " + std::to_string(offset * 180.0 / M_PI) + " deg")
125 .c_str()
126 : "");
127 }
128 }
129
130 if (t > params_.timeoutS)
131 {
132 RCLCPP_ERROR(
133 getLogger(),
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,
137 drift / params_.windowS * 180.0 / M_PI);
138 this->postPx4Failure();
139 return;
140 }
141 rate.sleep();
142 }
143 RCLCPP_WARN(getLogger(), "CbWaitForHeadingStable: shutdown requested");
144 this->postPx4Failure();
145}
virtual rclcpp::Logger getLogger() const
bool isShutdownRequested()
onEntry is executed in a new thread. However the current state cannot be left until the onEntry threa...
float wrapPi(float angle)

References cl_px4_mr::HeadingStableParams::expectedHeadingRad, cl_px4_mr::CpVehicleLocalPosition::getHeading(), smacc2::ISmaccClientBehavior::getLogger(), cl_px4_mr::HeadingStableParams::headingTolRad, smacc2::SmaccAsyncClientBehavior::isShutdownRequested(), cl_px4_mr::CpVehicleLocalPosition::isValid(), cl_px4_mr::CbPx4ClientBehaviorBase::localPosition_, cl_px4_mr::HeadingStableParams::maxDriftRadS, params_, cl_px4_mr::CbPx4ClientBehaviorBase::postPx4Failure(), cl_px4_mr::CbPx4ClientBehaviorBase::postPx4Success(), cl_px4_mr::HeadingStableParams::timeoutS, cl_px4_mr::HeadingStableParams::windowS, and cl_px4_mr::wrapPi().

Here is the call graph for this function:

◆ onExit()

void cl_px4_mr::CbWaitForHeadingStable::onExit ( )
inlineoverridevirtual

Reimplemented from smacc2::ISmaccClientBehavior.

Definition at line 53 of file cb_wait_for_heading_stable.hpp.

53{}

Member Data Documentation

◆ params_

HeadingStableParams cl_px4_mr::CbWaitForHeadingStable::params_
private

Definition at line 56 of file cb_wait_for_heading_stable.hpp.

Referenced by onEntry().


The documentation for this class was generated from the following files: