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

#include <cp_forward_obstacle_guard.hpp>

Inheritance diagram for cl_px4_mr::CpForwardObstacleGuard:
Inheritance graph
Collaboration diagram for cl_px4_mr::CpForwardObstacleGuard:
Collaboration graph

Public Member Functions

 CpForwardObstacleGuard (ForwardObstacleGuardParams params={})
 
virtual ~CpForwardObstacleGuard ()
 
void onInitialize () override
 
template<typename T >
smacc2::SmaccSignalConnection onObstacleTooClose (void(T::*callback)(), T *object)
 
template<typename T >
smacc2::SmaccSignalConnection onObstacleCleared (void(T::*callback)(), T *object)
 
void reset ()
 
bool isTooClose () const
 
float lastYawRate () const
 
float lastMinRange () const
 
int lastHits () const
 
const ForwardObstacleGuardParams & params () const
 
- Public Member Functions inherited from smacc2::ISmaccComponent
 ISmaccComponent ()
 
virtual ~ISmaccComponent ()
 
virtual std::string getName () const
 

Public Attributes

smacc2::SmaccSignal< void()> onObstacleTooClose_
 
smacc2::SmaccSignal< void()> onObstacleCleared_
 

Private Member Functions

void onCloud (const sensor_msgs::msg::PointCloud2 &msg)
 
void onAttitude (const px4_msgs::msg::VehicleAttitude::SharedPtr msg)
 
bool levelRotation (std::array< float, 9 > &r) const
 

Private Attributes

ForwardObstacleGuardParams params_
 
smacc2::client_core_components::CpTopicSubscriber< sensor_msgs::msg::PointCloud2 > * subscriber_
 
rclcpp::Subscription< px4_msgs::msg::VehicleAttitude >::SharedPtr attitudeSub_
 
double lastYaw_ = 0.0
 
uint64_t lastYawStampUs_ = 0
 
std::mutex attitudeMutex_
 
std::array< float, 4 > attitudeQ_ {{1.0f, 0.0f, 0.0f, 0.0f}}
 
bool haveAttitude_ = false
 
std::atomic< float > yawRate_ {0.0f}
 
int gatedClouds_ = 0
 
float cosHalfAngle_ = 1.0f
 
int triggerStreak_ = 0
 
int clearStreak_ = 0
 
std::atomic< bool > tooClose_ {false}
 
std::atomic< float > lastMinRange_ {std::numeric_limits<float>::infinity()}
 
std::atomic< int > lastHits_ {0}
 

Additional Inherited Members

- Protected Member Functions inherited from smacc2::ISmaccComponent
template<typename TOrthogonal , typename TClient >
void onComponentInitialization ()
 
template<typename EventType >
void postEvent (const EventType &ev)
 
template<typename EventType >
void postEvent ()
 
template<typename TOrthogonal , typename TSourceObject >
void onStateOrthogonalAllocation ()
 
template<typename TComponent >
void requiresComponent (TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
template<typename TComponent >
void requiresComponent (std::string name, TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
template<typename TClient >
void requiresClient (TClient *&requiredClientStorage)
 
template<typename SmaccComponentType , typename TOrthogonal , typename TClient , typename... TArgs>
SmaccComponentType * createSiblingComponent (TArgs... targs)
 
template<typename SmaccComponentType , typename TOrthogonal , typename TClient , typename... TArgs>
SmaccComponentType * createSiblingNamedComponent (std::string name, TArgs... targs)
 
rclcpp::Node::SharedPtr getNode ()
 
rclcpp::Logger getLogger () const
 
ISmaccStateMachine * getStateMachine ()
 
- Protected Attributes inherited from smacc2::ISmaccComponent
ISmaccStateMachine * stateMachine_
 
ISmaccClient * owner_
 

Detailed Description

Definition at line 85 of file cp_forward_obstacle_guard.hpp.

Constructor & Destructor Documentation

◆ CpForwardObstacleGuard()

cl_px4_mr::CpForwardObstacleGuard::CpForwardObstacleGuard ( ForwardObstacleGuardParams params = {})
explicit

◆ ~CpForwardObstacleGuard()

cl_px4_mr::CpForwardObstacleGuard::~CpForwardObstacleGuard ( )
virtual

Definition at line 37 of file cp_forward_obstacle_guard.cpp.

37{}

Member Function Documentation

◆ isTooClose()

bool cl_px4_mr::CpForwardObstacleGuard::isTooClose ( ) const
inline

Definition at line 111 of file cp_forward_obstacle_guard.hpp.

111{ return tooClose_.load(); }

References tooClose_.

◆ lastHits()

int cl_px4_mr::CpForwardObstacleGuard::lastHits ( ) const
inline

Definition at line 114 of file cp_forward_obstacle_guard.hpp.

114{ return lastHits_.load(); }

References lastHits_.

◆ lastMinRange()

float cl_px4_mr::CpForwardObstacleGuard::lastMinRange ( ) const
inline

Definition at line 113 of file cp_forward_obstacle_guard.hpp.

113{ return lastMinRange_.load(); }

References lastMinRange_.

◆ lastYawRate()

float cl_px4_mr::CpForwardObstacleGuard::lastYawRate ( ) const
inline

Definition at line 112 of file cp_forward_obstacle_guard.hpp.

112{ return yawRate_.load(); }

References yawRate_.

◆ levelRotation()

bool cl_px4_mr::CpForwardObstacleGuard::levelRotation ( std::array< float, 9 > & r) const
private

Definition at line 103 of file cp_forward_obstacle_guard.cpp.

104{
105 std::array<float, 4> q;
106 {
107 std::lock_guard<std::mutex> lock(attitudeMutex_);
108 if (!haveAttitude_)
109 {
110 return false;
111 }
112 q = attitudeQ_;
113 }
114 // body FLU -> ENU (px4_ros_com constants), then strip the yaw so the result
115 // is the roll/pitch-only rotation into a level, heading-aligned frame
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;
120 qEnuFlu.normalize();
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)
127 {
128 for (int j = 0; j < 3; ++j)
129 {
130 r[i * 3 + j] = static_cast<float>(level[i][j]);
131 }
132 }
133 return true;
134}
const tf2::Quaternion kFrdFluQ(1.0, 0.0, 0.0, 0.0)
const tf2::Quaternion kNedEnuQ(0.70710678118654752, 0.70710678118654752, 0.0, 0.0)

References attitudeMutex_, attitudeQ_, and haveAttitude_.

Referenced by onCloud().

Here is the caller graph for this function:

◆ onAttitude()

void cl_px4_mr::CpForwardObstacleGuard::onAttitude ( const px4_msgs::msg::VehicleAttitude::SharedPtr msg)
private

Definition at line 78 of file cp_forward_obstacle_guard.cpp.

79{
80 // yaw rate by finite difference of the NED heading (PX4 does not bridge
81 // vehicle_angular_velocity by default); light EMA against quantisation
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));
84 if (lastYawStampUs_ != 0 && msg->timestamp > lastYawStampUs_)
85 {
86 const double dt = static_cast<double>(msg->timestamp - lastYawStampUs_) * 1e-6;
87 double d = yaw - lastYaw_;
88 d = std::atan2(std::sin(d), std::cos(d));
89 if (dt > 1e-4 && dt < 0.5)
90 {
91 const float rate = static_cast<float>(d / dt);
92 yawRate_ = 0.5f * yawRate_.load() + 0.5f * rate;
93 }
94 }
95 lastYaw_ = yaw;
96 lastYawStampUs_ = msg->timestamp;
97
98 std::lock_guard<std::mutex> lock(attitudeMutex_);
99 attitudeQ_ = {msg->q[0], msg->q[1], msg->q[2], msg->q[3]};
100 haveAttitude_ = true;
101}

References attitudeMutex_, attitudeQ_, haveAttitude_, lastYaw_, lastYawStampUs_, and yawRate_.

Referenced by onInitialize().

Here is the caller graph for this function:

◆ onCloud()

void cl_px4_mr::CpForwardObstacleGuard::onCloud ( const sensor_msgs::msg::PointCloud2 & msg)
private

Definition at line 136 of file cp_forward_obstacle_guard.cpp.

137{
138 if (params_.maxYawRateRadS > 0.0f && std::fabs(yawRate_.load()) > params_.maxYawRateRadS)
139 {
140 // turning: the cone is sweeping sideways; keep the current flag, count nothing
141 if (++gatedClouds_ == 1)
142 {
143 RCLCPP_INFO(
144 getLogger(), "CpForwardObstacleGuard: yawing at %.2f rad/s - cone gated", yawRate_.load());
145 }
146 return;
147 }
148 if (gatedClouds_ > 0)
149 {
150 RCLCPP_INFO(
151 getLogger(), "CpForwardObstacleGuard: cone active again after %d gated clouds", gatedClouds_);
152 gatedClouds_ = 0;
153 triggerStreak_ = 0;
154 }
155
156 int hits = 0;
157 float minRange = std::numeric_limits<float>::infinity();
158
159 std::array<float, 9> r{};
160 const bool level = params_.levelFrame && levelRotation(r);
161
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)
166 {
167 float x = *ix;
168 float y = *iy;
169 float z = *iz;
170 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z))
171 {
172 continue; // gz reports no-return as inf (is_dense = false)
173 }
174 if (level)
175 {
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;
179 x = lx;
180 y = ly;
181 z = lz;
182 }
183 if (params_.floorCutoffM > 0.0f && z < -params_.floorCutoffM)
184 {
185 continue; // the floor, not something in the way
186 }
187 const float r = std::sqrt(x * x + y * y + z * z);
188 if (r < params_.minRangeM || r > params_.clearRangeM)
189 {
190 continue;
191 }
192 if (x / r < cosHalfAngle_)
193 {
194 continue; // outside the forward cone
195 }
196 if (r < minRange)
197 {
198 minRange = r;
199 }
200 if (r < params_.triggerRangeM)
201 {
202 ++hits;
203 }
204 }
205
206 lastMinRange_ = minRange;
207 lastHits_ = hits;
208
209 const bool triggering = hits >= params_.minHits;
210 // cleared only when nothing in the cone is below the clear range at all
211 const bool clear = !(minRange < params_.clearRangeM);
212
213 if (!tooClose_)
214 {
215 triggerStreak_ = triggering ? triggerStreak_ + 1 : 0;
217 {
218 tooClose_ = true;
219 clearStreak_ = 0;
220 RCLCPP_WARN(
221 getLogger(), "CpForwardObstacleGuard: OBSTACLE min range %.2f m (%d hits in cone)",
222 minRange, hits);
224 }
225 }
226 else
227 {
228 clearStreak_ = clear ? clearStreak_ + 1 : 0;
230 {
231 tooClose_ = false;
232 triggerStreak_ = 0;
233 RCLCPP_INFO(getLogger(), "CpForwardObstacleGuard: cleared (min range %.2f m)", minRange);
235 }
236 }
237}
bool levelRotation(std::array< float, 9 > &r) const
smacc2::SmaccSignal< void()> onObstacleCleared_
smacc2::SmaccSignal< void()> onObstacleTooClose_
rclcpp::Logger getLogger() const

References cl_px4_mr::ForwardObstacleGuardParams::clearClouds, cl_px4_mr::ForwardObstacleGuardParams::clearRangeM, clearStreak_, cosHalfAngle_, cl_px4_mr::ForwardObstacleGuardParams::floorCutoffM, gatedClouds_, smacc2::ISmaccComponent::getLogger(), lastHits_, lastMinRange_, cl_px4_mr::ForwardObstacleGuardParams::levelFrame, levelRotation(), cl_px4_mr::ForwardObstacleGuardParams::maxYawRateRadS, cl_px4_mr::ForwardObstacleGuardParams::minHits, onObstacleCleared_, onObstacleTooClose_, params_, tooClose_, cl_px4_mr::ForwardObstacleGuardParams::triggerClouds, cl_px4_mr::ForwardObstacleGuardParams::triggerRangeM, triggerStreak_, and yawRate_.

Referenced by onInitialize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onInitialize()

void cl_px4_mr::CpForwardObstacleGuard::onInitialize ( )
overridevirtual

Reimplemented from smacc2::ISmaccComponent.

Definition at line 39 of file cp_forward_obstacle_guard.cpp.

40{
42 if (subscriber_ == nullptr)
43 {
44 RCLCPP_ERROR(
45 getLogger(),
46 "CpForwardObstacleGuard: no CpTopicSubscriber<PointCloud2> on this client - guard inactive");
47 return;
48 }
51 {
52 attitudeSub_ = this->getNode()->create_subscription<px4_msgs::msg::VehicleAttitude>(
53 "/fmu/out/vehicle_attitude", rclcpp::SensorDataQoS(),
54 std::bind(&CpForwardObstacleGuard::onAttitude, this, std::placeholders::_1));
55 }
56 RCLCPP_INFO(
57 getLogger(),
58 "CpForwardObstacleGuard: subscribed - cone %.0f deg, trigger < %.1f m, clear > %.1f m, "
59 "%d hits, %d/%d clouds, yaw-rate gate %.2f rad/s, floor cutoff %.1f m, level frame %s",
62 params_.floorCutoffM, params_.levelFrame ? "on" : "off");
63}
smacc2::client_core_components::CpTopicSubscriber< sensor_msgs::msg::PointCloud2 > * subscriber_
void onAttitude(const px4_msgs::msg::VehicleAttitude::SharedPtr msg)
void onCloud(const sensor_msgs::msg::PointCloud2 &msg)
rclcpp::Subscription< px4_msgs::msg::VehicleAttitude >::SharedPtr attitudeSub_
void requiresComponent(TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
rclcpp::Node::SharedPtr getNode()
smacc2::SmaccSignalConnection onMessageReceived(void(T::*callback)(const MessageType &), T *object)

References attitudeSub_, cl_px4_mr::ForwardObstacleGuardParams::clearClouds, cl_px4_mr::ForwardObstacleGuardParams::clearRangeM, cl_px4_mr::ForwardObstacleGuardParams::floorCutoffM, smacc2::ISmaccComponent::getLogger(), smacc2::ISmaccComponent::getNode(), cl_px4_mr::ForwardObstacleGuardParams::halfAngleRad, cl_px4_mr::ForwardObstacleGuardParams::levelFrame, cl_px4_mr::ForwardObstacleGuardParams::maxYawRateRadS, cl_px4_mr::ForwardObstacleGuardParams::minHits, onAttitude(), onCloud(), smacc2::client_core_components::CpTopicSubscriber< MessageType >::onMessageReceived(), params_, smacc2::ISmaccComponent::requiresComponent(), subscriber_, cl_px4_mr::ForwardObstacleGuardParams::triggerClouds, and cl_px4_mr::ForwardObstacleGuardParams::triggerRangeM.

Here is the call graph for this function:

◆ onObstacleCleared()

template<typename T >
smacc2::SmaccSignalConnection cl_px4_mr::CpForwardObstacleGuard::onObstacleCleared ( void(T::* callback )(),
T * object )
inline

Definition at line 100 of file cp_forward_obstacle_guard.hpp.

101 {
102 return this->getStateMachine()->createSignalConnection(onObstacleCleared_, callback, object);
103 }
ISmaccStateMachine * getStateMachine()
smacc2::SmaccSignalConnection createSignalConnection(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object)

References smacc2::ISmaccStateMachine::createSignalConnection(), smacc2::ISmaccComponent::getStateMachine(), and onObstacleCleared_.

Referenced by cl_px4_mr::CbObstacleGuard::onEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onObstacleTooClose()

template<typename T >
smacc2::SmaccSignalConnection cl_px4_mr::CpForwardObstacleGuard::onObstacleTooClose ( void(T::* callback )(),
T * object )
inline

Definition at line 94 of file cp_forward_obstacle_guard.hpp.

95 {
96 return this->getStateMachine()->createSignalConnection(onObstacleTooClose_, callback, object);
97 }

References smacc2::ISmaccStateMachine::createSignalConnection(), smacc2::ISmaccComponent::getStateMachine(), and onObstacleTooClose_.

Referenced by cl_px4_mr::CbObstacleGuard::onEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ params()

const ForwardObstacleGuardParams & cl_px4_mr::CpForwardObstacleGuard::params ( ) const
inline

Definition at line 115 of file cp_forward_obstacle_guard.hpp.

115{ return params_; }

References params_.

◆ reset()

void cl_px4_mr::CpForwardObstacleGuard::reset ( )

Definition at line 65 of file cp_forward_obstacle_guard.cpp.

66{
67 const bool was = tooClose_.exchange(false);
69 clearStreak_ = 0;
70 if (was)
71 {
72 RCLCPP_INFO(
73 getLogger(), "CpForwardObstacleGuard: reset (stale flag dropped, last min range %.2f m)",
74 lastMinRange_.load());
75 }
76}

References clearStreak_, smacc2::ISmaccComponent::getLogger(), lastMinRange_, tooClose_, and triggerStreak_.

Referenced by cl_px4_mr::CbObstacleGuard::onEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ attitudeMutex_

std::mutex cl_px4_mr::CpForwardObstacleGuard::attitudeMutex_
mutableprivate

Definition at line 132 of file cp_forward_obstacle_guard.hpp.

Referenced by levelRotation(), and onAttitude().

◆ attitudeQ_

std::array<float, 4> cl_px4_mr::CpForwardObstacleGuard::attitudeQ_ {{1.0f, 0.0f, 0.0f, 0.0f}}
private

Definition at line 133 of file cp_forward_obstacle_guard.hpp.

133{{1.0f, 0.0f, 0.0f, 0.0f}}; // PX4 order w, x, y, z

Referenced by levelRotation(), and onAttitude().

◆ attitudeSub_

rclcpp::Subscription<px4_msgs::msg::VehicleAttitude>::SharedPtr cl_px4_mr::CpForwardObstacleGuard::attitudeSub_
private

Definition at line 129 of file cp_forward_obstacle_guard.hpp.

Referenced by onInitialize().

◆ clearStreak_

int cl_px4_mr::CpForwardObstacleGuard::clearStreak_ = 0
private

Definition at line 139 of file cp_forward_obstacle_guard.hpp.

Referenced by onCloud(), and reset().

◆ cosHalfAngle_

float cl_px4_mr::CpForwardObstacleGuard::cosHalfAngle_ = 1.0f
private

Definition at line 137 of file cp_forward_obstacle_guard.hpp.

Referenced by onCloud().

◆ gatedClouds_

int cl_px4_mr::CpForwardObstacleGuard::gatedClouds_ = 0
private

Definition at line 136 of file cp_forward_obstacle_guard.hpp.

Referenced by onCloud().

◆ haveAttitude_

bool cl_px4_mr::CpForwardObstacleGuard::haveAttitude_ = false
private

Definition at line 134 of file cp_forward_obstacle_guard.hpp.

Referenced by levelRotation(), and onAttitude().

◆ lastHits_

std::atomic<int> cl_px4_mr::CpForwardObstacleGuard::lastHits_ {0}
private

Definition at line 142 of file cp_forward_obstacle_guard.hpp.

142{0};

Referenced by lastHits(), and onCloud().

◆ lastMinRange_

std::atomic<float> cl_px4_mr::CpForwardObstacleGuard::lastMinRange_ {std::numeric_limits<float>::infinity()}
private

Definition at line 141 of file cp_forward_obstacle_guard.hpp.

141{std::numeric_limits<float>::infinity()};

Referenced by lastMinRange(), onCloud(), and reset().

◆ lastYaw_

double cl_px4_mr::CpForwardObstacleGuard::lastYaw_ = 0.0
private

Definition at line 130 of file cp_forward_obstacle_guard.hpp.

Referenced by onAttitude().

◆ lastYawStampUs_

uint64_t cl_px4_mr::CpForwardObstacleGuard::lastYawStampUs_ = 0
private

Definition at line 131 of file cp_forward_obstacle_guard.hpp.

Referenced by onAttitude().

◆ onObstacleCleared_

smacc2::SmaccSignal<void()> cl_px4_mr::CpForwardObstacleGuard::onObstacleCleared_

Definition at line 118 of file cp_forward_obstacle_guard.hpp.

Referenced by onCloud(), and onObstacleCleared().

◆ onObstacleTooClose_

smacc2::SmaccSignal<void()> cl_px4_mr::CpForwardObstacleGuard::onObstacleTooClose_

Definition at line 117 of file cp_forward_obstacle_guard.hpp.

Referenced by onCloud(), and onObstacleTooClose().

◆ params_

ForwardObstacleGuardParams cl_px4_mr::CpForwardObstacleGuard::params_
private

Definition at line 126 of file cp_forward_obstacle_guard.hpp.

Referenced by onCloud(), onInitialize(), and params().

◆ subscriber_

smacc2::client_core_components::CpTopicSubscriber<sensor_msgs::msg::PointCloud2>* cl_px4_mr::CpForwardObstacleGuard::subscriber_
private
Initial value:
=
nullptr

Definition at line 127 of file cp_forward_obstacle_guard.hpp.

Referenced by onInitialize().

◆ tooClose_

std::atomic<bool> cl_px4_mr::CpForwardObstacleGuard::tooClose_ {false}
private

Definition at line 140 of file cp_forward_obstacle_guard.hpp.

140{false};

Referenced by isTooClose(), onCloud(), and reset().

◆ triggerStreak_

int cl_px4_mr::CpForwardObstacleGuard::triggerStreak_ = 0
private

Definition at line 138 of file cp_forward_obstacle_guard.hpp.

Referenced by onCloud(), and reset().

◆ yawRate_

std::atomic<float> cl_px4_mr::CpForwardObstacleGuard::yawRate_ {0.0f}
private

Definition at line 135 of file cp_forward_obstacle_guard.hpp.

135{0.0f};

Referenced by lastYawRate(), onAttitude(), and onCloud().


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