SMACC2
Loading...
Searching...
No Matches
cl_px4_mr Namespace Reference

Namespaces

namespace  anonymous_namespace{cb_wait_for_heading_stable.cpp}
 
namespace  anonymous_namespace{cp_kml_mission_loader.cpp}
 
namespace  anonymous_namespace{cp_tf_broadcaster.cpp}
 
namespace  anonymous_namespace{cp_tunnel_centering.cpp}
 
namespace  anonymous_namespace{pattern_generators.cpp}
 
namespace  geo_detail
 
namespace  pattern_detail
 

Classes

class  CbArmPX4
 
class  CbAscendToAltitude
 
class  CbChangeAltitude
 
class  CbConnectMicroRosAgent
 
class  CbDisarmPX4
 
class  CbFigureEight
 
class  CbFollowNedPath
 
class  CbFollowWaypoints
 
class  CbGoToLocation
 
class  CbGridPattern
 
class  CbHoldPosition
 
class  CbLand
 
class  CbLawnmower
 
class  CbLemniscate
 
class  CbLoadKmlMission
 
class  CbLoiter
 
class  CbObstacleGuard
 
class  CbOrbitLocation
 
class  CbPx4ClientBehaviorBase
 
class  CbPx4PathFollowerBase
 
class  CbReturnToHome
 
class  CbSineAltitudeCruise
 
class  CbSineWaveHorizontal
 
class  CbSineWaveVertical
 
class  CbSpiral
 
class  CbSpiralPattern
 
class  CbSpiralUp
 
class  CbSquareSpiral
 
class  CbTakeOff
 
class  CbVSSearch
 
class  CbWaitForHeadingStable
 
class  CbYawRotate
 
class  CbYawScan
 
class  ClPx4Mr
 
class  CpForwardObstacleGuard
 
class  CpGoalChecker
 
class  CpKmlMissionLoader
 
class  CpMicroRosAgent
 
class  CpOffboardKeepAlive
 
class  CpTfBroadcaster
 
class  CpTrajectorySetpoint
 
class  CpTunnelCentering
 
class  CpVehicleCommand
 
class  CpVehicleCommandAck
 
class  CpVehicleLocalPosition
 
class  CpVehicleStatus
 
struct  EvObstacleCleared
 
struct  EvObstacleTooClose
 
struct  FlightPatternAscendParams
 
struct  FlightPatternFigureEightParams
 
struct  FlightPatternGridPatternParams
 
struct  FlightPatternLawnmowerParams
 
struct  FlightPatternLoiterParams
 
struct  FlightPatternSineWaveHorizontalParams
 
struct  FlightPatternSineWaveVerticalParams
 
struct  FlightPatternSpiralParams
 
struct  FlightPatternSquareSpiralParams
 
struct  FlightPatternVSSearchParams
 
struct  ForwardObstacleGuardParams
 
struct  GeoPoint
 
struct  HeadingStableParams
 
struct  KmlLoadResult
 
class  MapProjection
 
struct  NedPoint
 
struct  PathFollowerParams
 
struct  SpiralUpParams
 
struct  TfBroadcasterParams
 
struct  TunnelCenteringParams
 

Enumerations

enum class  YawMode { TANGENT , FIXED , PER_VERTEX , HOLD_ENTRY }
 
enum class  Turn { RIGHT , LEFT }
 

Functions

float wrapPi (float angle)
 
double haversineDistance (double lat1, double lon1, double lat2, double lon2)
 
double haversineDistance (const GeoPoint &a, const GeoPoint &b)
 
double initialBearing (double lat1, double lon1, double lat2, double lon2)
 
float nedDistance (const NedPoint &a, const NedPoint &b)
 
float nedDistanceXY (const NedPoint &a, const NedPoint &b)
 
std::vector< float > cumulativeLengths (const std::vector< NedPoint > &path)
 
float polylineLength (const std::vector< NedPoint > &path)
 
NedPoint sampleAtArcLength (const std::vector< NedPoint > &path, const std::vector< float > &cum, float s, size_t *segmentIndex=nullptr)
 
std::vector< NedPoint > resamplePolyline (const std::vector< NedPoint > &path, float spacing)
 
void levelRotationFromPx4Quaternion (const std::array< float, 4 > &q, std::array< float, 9 > &r)
 
float turnSign (Turn t)
 
const char * turnName (Turn t)
 
std::vector< NedPoint > generateFlightPatternAscend (const FlightPatternAscendParams &p, const NedPoint &current)
 
std::vector< NedPoint > generateFlightPatternLoiter (const FlightPatternLoiterParams &p, const NedPoint &current)
 
std::vector< NedPoint > generateFlightPatternFigureEight (const FlightPatternFigureEightParams &p, const NedPoint &current)
 
float flightPatternFigureEightLength (const FlightPatternFigureEightParams &p)
 
std::vector< NedPoint > generateFlightPatternSineWaveVertical (const FlightPatternSineWaveVerticalParams &p, const NedPoint &current)
 
std::vector< NedPoint > generateFlightPatternSineWaveHorizontal (const FlightPatternSineWaveHorizontalParams &p, const NedPoint &current)
 
std::vector< NedPoint > generateFlightPatternSquareSpiral (const FlightPatternSquareSpiralParams &p, const NedPoint &current)
 
float flightPatternSquareSpiralLength (const FlightPatternSquareSpiralParams &p)
 
std::vector< NedPoint > generateFlightPatternSpiral (const FlightPatternSpiralParams &p, const NedPoint &current)
 
float flightPatternSpiralLength (const FlightPatternSpiralParams &p)
 
std::vector< NedPoint > generateFlightPatternLawnmower (const FlightPatternLawnmowerParams &p, const NedPoint &current)
 
float flightPatternLawnmowerLength (const FlightPatternLawnmowerParams &p)
 
int flightPatternLawnmowerLaneCount (const FlightPatternLawnmowerParams &p)
 
std::vector< NedPoint > generateFlightPatternGridPattern (const FlightPatternGridPatternParams &p, const NedPoint &current)
 
float flightPatternGridPatternLength (const FlightPatternGridPatternParams &p)
 
std::vector< NedPoint > generateFlightPatternVSSearch (const FlightPatternVSSearchParams &p, const NedPoint &current)
 
float flightPatternVSSearchLength (const FlightPatternVSSearchParams &p)
 
float legHeading (const NedPoint &from, const NedPoint &to)
 

Variables

constexpr double kEarthRadiusM = 6371000.0
 

Enumeration Type Documentation

◆ Turn

enum class cl_px4_mr::Turn
strong
Enumerator
RIGHT 
LEFT 

Definition at line 51 of file pattern_generators.hpp.

◆ YawMode

enum class cl_px4_mr::YawMode
strong
Enumerator
TANGENT 
FIXED 
PER_VERTEX 
HOLD_ENTRY 

Definition at line 35 of file cb_px4_path_follower_base.hpp.

36{
37 TANGENT, // along the current path segment
38 FIXED, // PathFollowerParams::fixedYaw
39 PER_VERTEX, // NedPoint::yaw of the segment start (NaN -> tangent)
40 HOLD_ENTRY // heading at entry
41};

Function Documentation

◆ cumulativeLengths()

std::vector< float > cl_px4_mr::cumulativeLengths ( const std::vector< NedPoint > & path)
inline

Definition at line 205 of file geo_utils.hpp.

206{
207 std::vector<float> cum;
208 cum.reserve(path.size());
209 double acc = 0.0;
210 for (size_t i = 0; i < path.size(); ++i)
211 {
212 if (i > 0)
213 {
214 acc += static_cast<double>(nedDistance(path[i - 1], path[i]));
215 }
216 cum.push_back(static_cast<float>(acc));
217 }
218 return cum;
219}
float nedDistance(const NedPoint &a, const NedPoint &b)

References nedDistance().

Referenced by cl_px4_mr::CbPx4PathFollowerBase::onEntry(), and polylineLength().

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

◆ flightPatternFigureEightLength()

float cl_px4_mr::flightPatternFigureEightLength ( const FlightPatternFigureEightParams & p)

Definition at line 183 of file pattern_generators.cpp.

184{
185 // perimeter of the lemniscate of Bernoulli = 5.2441 a
186 return 5.2441f * std::max(p.size, 0.5f) * std::max(p.count, 0);
187}

References cl_px4_mr::FlightPatternFigureEightParams::count, and cl_px4_mr::FlightPatternFigureEightParams::size.

Referenced by cl_px4_mr::CbLemniscate::buildPath().

Here is the caller graph for this function:

◆ flightPatternGridPatternLength()

◆ flightPatternLawnmowerLaneCount()

int cl_px4_mr::flightPatternLawnmowerLaneCount ( const FlightPatternLawnmowerParams & p)

Definition at line 363 of file pattern_generators.cpp.

364{
365 const float spacing = std::max(p.laneSpacing, 0.5f);
366 return std::max(1, static_cast<int>(std::floor(std::max(p.width, 0.0f) / spacing + 1e-3f)) + 1);
367}

References cl_px4_mr::FlightPatternLawnmowerParams::laneSpacing, and cl_px4_mr::FlightPatternLawnmowerParams::width.

Referenced by cl_px4_mr::CbLawnmower::buildPath(), flightPatternLawnmowerLength(), and generateFlightPatternLawnmower().

Here is the caller graph for this function:

◆ flightPatternLawnmowerLength()

float cl_px4_mr::flightPatternLawnmowerLength ( const FlightPatternLawnmowerParams & p)

Definition at line 369 of file pattern_generators.cpp.

370{
371 const int lanes = flightPatternLawnmowerLaneCount(p);
372 return lanes * std::max(p.laneLength, 0.0f) + (lanes - 1) * std::max(p.laneSpacing, 0.5f);
373}
int flightPatternLawnmowerLaneCount(const FlightPatternLawnmowerParams &p)

References flightPatternLawnmowerLaneCount(), cl_px4_mr::FlightPatternLawnmowerParams::laneLength, and cl_px4_mr::FlightPatternLawnmowerParams::laneSpacing.

Referenced by cl_px4_mr::CbLawnmower::buildPath(), and flightPatternGridPatternLength().

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

◆ flightPatternSpiralLength()

float cl_px4_mr::flightPatternSpiralLength ( const FlightPatternSpiralParams & p)

Definition at line 354 of file pattern_generators.cpp.

355{
356 // area between the radii divided by the track spacing
357 const float rStart = std::max(p.startRadius, 0.0f);
358 const float rEnd = std::max(p.endRadius, rStart);
359 const float spacing = std::max(p.spacing, 0.5f);
360 return static_cast<float>(M_PI) * (rEnd * rEnd - rStart * rStart) / spacing;
361}

References cl_px4_mr::FlightPatternSpiralParams::endRadius, cl_px4_mr::FlightPatternSpiralParams::spacing, and cl_px4_mr::FlightPatternSpiralParams::startRadius.

Referenced by cl_px4_mr::CbSpiral::buildPath().

Here is the caller graph for this function:

◆ flightPatternSquareSpiralLength()

float cl_px4_mr::flightPatternSquareSpiralLength ( const FlightPatternSquareSpiralParams & p)

Definition at line 291 of file pattern_generators.cpp.

292{
293 const float spacing = std::max(p.spacing, 0.5f);
294 float total = 0.0f;
295 for (int i = 0; i < p.numLegs; ++i)
296 {
297 const float len = spacing * static_cast<float>(i / 2 + 1);
298 if (p.maxLegLength > 0.0f && len > p.maxLegLength)
299 {
300 break;
301 }
302 total += len;
303 }
304 return total;
305}

References cl_px4_mr::FlightPatternSquareSpiralParams::maxLegLength, cl_px4_mr::FlightPatternSquareSpiralParams::numLegs, and cl_px4_mr::FlightPatternSquareSpiralParams::spacing.

Referenced by cl_px4_mr::CbSquareSpiral::buildPath().

Here is the caller graph for this function:

◆ flightPatternVSSearchLength()

float cl_px4_mr::flightPatternVSSearchLength ( const FlightPatternVSSearchParams & p)

Definition at line 480 of file pattern_generators.cpp.

481{
482 return 9.0f * std::max(p.radius, 1.0f) * static_cast<float>(std::max(p.cycles, 1));
483}

References cl_px4_mr::FlightPatternVSSearchParams::cycles, and cl_px4_mr::FlightPatternVSSearchParams::radius.

Referenced by cl_px4_mr::CbVSSearch::buildPath().

Here is the caller graph for this function:

◆ generateFlightPatternAscend()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternAscend ( const FlightPatternAscendParams & p,
const NedPoint & current )

Definition at line 33 of file pattern_generators.cpp.

35{
36 NedPoint target;
37 target.x = pick(p.targetX, current.x);
38 target.y = pick(p.targetY, current.y);
39 target.z = -p.altitudeAgl;
40
41 const bool atXy = std::hypot(target.x - current.x, target.y - current.y) <= p.tolerance;
42 if (atXy && std::fabs(current.z - target.z) <= p.tolerance)
43 {
44 return {target};
45 }
46 NedPoint start = current;
47 start.yaw = kNaN;
48 return {start, target};
49}

References cl_px4_mr::FlightPatternAscendParams::altitudeAgl, cl_px4_mr::FlightPatternAscendParams::targetX, cl_px4_mr::FlightPatternAscendParams::targetY, cl_px4_mr::FlightPatternAscendParams::tolerance, cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, cl_px4_mr::NedPoint::yaw, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbAscendToAltitude::buildPath().

Here is the caller graph for this function:

◆ generateFlightPatternFigureEight()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternFigureEight ( const FlightPatternFigureEightParams & p,
const NedPoint & current )

Definition at line 118 of file pattern_generators.cpp.

120{
121 const float cx = pick(p.centerX, current.x);
122 const float cy = pick(p.centerY, current.y);
123 const float z = altitudeToZ(p.altitudeAgl, current.z);
124 const float a = std::max(p.size, 0.5f);
125 const int n = std::max(p.pointsPerLoop, 16);
126 const float sign = turnSign(p.direction);
127
128 if (p.count <= 0)
129 {
130 NedPoint here = current;
131 here.z = z;
132 here.yaw = kNaN;
133 return {here};
134 }
135
136 // lobe axis: given, else the entry heading, else north
137 const float heading =
138 std::isnan(p.heading) ? (std::isnan(current.yaw) ? 0.0f : current.yaw) : p.heading;
139 const float ch = std::cos(heading);
140 const float sh = std::sin(heading);
141
142 // one loop of the lemniscate x = a cos t / (1 + sin^2 t), y = a sin t cos t / (1 + sin^2 t)
143 std::vector<NedPoint> loop;
144 loop.reserve(static_cast<size_t>(n));
145 for (int k = 0; k < n; ++k)
146 {
147 const float t = sign * 2.0f * static_cast<float>(M_PI) * k / n;
148 const float st = std::sin(t);
149 const float ct = std::cos(t);
150 const float denom = 1.0f + st * st;
151 const float lx = a * ct / denom;
152 const float ly = a * st * ct / denom;
153 NedPoint v;
154 v.x = cx + lx * ch - ly * sh;
155 v.y = cy + lx * sh + ly * ch;
156 v.z = z;
157 v.yaw = kNaN;
158 loop.push_back(v);
159 }
160
161 // enter at the sample nearest the vehicle
162 int start = 0;
163 float best = std::numeric_limits<float>::infinity();
164 for (int k = 0; k < n; ++k)
165 {
166 const float d = std::hypot(loop[k].x - current.x, loop[k].y - current.y);
167 if (d < best)
168 {
169 best = d;
170 start = k;
171 }
172 }
173
174 std::vector<NedPoint> path;
175 path.reserve(static_cast<size_t>(p.count * n + 1));
176 for (int k = 0; k <= p.count * n; ++k)
177 {
178 path.push_back(loop[static_cast<size_t>((start + k) % n)]);
179 }
180 return path;
181}
float turnSign(Turn t)

References cl_px4_mr::FlightPatternFigureEightParams::altitudeAgl, cl_px4_mr::FlightPatternFigureEightParams::centerX, cl_px4_mr::FlightPatternFigureEightParams::centerY, cl_px4_mr::FlightPatternFigureEightParams::count, cl_px4_mr::FlightPatternFigureEightParams::direction, cl_px4_mr::FlightPatternFigureEightParams::heading, cl_px4_mr::FlightPatternFigureEightParams::pointsPerLoop, cl_px4_mr::FlightPatternFigureEightParams::size, turnSign(), cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, cl_px4_mr::NedPoint::yaw, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbLemniscate::buildPath().

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

◆ generateFlightPatternGridPattern()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternGridPattern ( const FlightPatternGridPatternParams & p,
const NedPoint & current )

Definition at line 435 of file pattern_generators.cpp.

437{
439 first.originIsCenter = true; // the grid is always centred on the origin
440 first.originX = pick(p.base.originX, current.x);
441 first.originY = pick(p.base.originY, current.y);
442 first.laneHeading = pick(p.base.laneHeading, std::isnan(current.yaw) ? 0.0f : current.yaw);
443
444 std::vector<NedPoint> path = generateFlightPatternLawnmower(first, current);
445 if (!p.secondPass || path.empty())
446 {
447 return path;
448 }
449
450 // second pass: rotated 90 degrees over the same rectangle; try the four
451 // start corners (heading +-90, step side left/right) and take the one that
452 // starts nearest the end of pass 1
453 const NedPoint & joint = path.back();
454 std::vector<NedPoint> best;
455 float bestDist = std::numeric_limits<float>::max();
456 for (int variant = 0; variant < 4; ++variant)
457 {
458 FlightPatternLawnmowerParams second = first;
459 second.laneLength = first.width;
460 second.width = first.laneLength;
461 second.laneHeading =
462 first.laneHeading + ((variant & 1) ? -1.0f : 1.0f) * static_cast<float>(M_PI) / 2.0f;
463 second.firstTurn = (variant & 2) ? Turn::LEFT : Turn::RIGHT;
464 std::vector<NedPoint> candidate = generateFlightPatternLawnmower(second, current);
465 if (candidate.empty())
466 {
467 continue;
468 }
469 const float d = nedDistance(joint, candidate.front());
470 if (d < bestDist)
471 {
472 bestDist = d;
473 best = std::move(candidate);
474 }
475 }
476 path.insert(path.end(), best.begin(), best.end());
477 return path;
478}
std::vector< NedPoint > generateFlightPatternLawnmower(const FlightPatternLawnmowerParams &p, const NedPoint &current)

References cl_px4_mr::FlightPatternGridPatternParams::base, cl_px4_mr::FlightPatternLawnmowerParams::firstTurn, generateFlightPatternLawnmower(), cl_px4_mr::FlightPatternLawnmowerParams::laneHeading, cl_px4_mr::FlightPatternLawnmowerParams::laneLength, LEFT, nedDistance(), cl_px4_mr::FlightPatternLawnmowerParams::originIsCenter, cl_px4_mr::FlightPatternLawnmowerParams::originX, cl_px4_mr::FlightPatternLawnmowerParams::originY, RIGHT, cl_px4_mr::FlightPatternGridPatternParams::secondPass, cl_px4_mr::FlightPatternLawnmowerParams::width, cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, and cl_px4_mr::NedPoint::yaw.

Referenced by cl_px4_mr::CbGridPattern::buildPath().

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

◆ generateFlightPatternLawnmower()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternLawnmower ( const FlightPatternLawnmowerParams & p,
const NedPoint & current )

Definition at line 375 of file pattern_generators.cpp.

377{
378 const float z = altitudeToZ(p.altitudeAgl, current.z);
379 const float heading = pick(p.laneHeading, std::isnan(current.yaw) ? 0.0f : current.yaw);
380 const float ux = std::cos(heading);
381 const float uy = std::sin(heading);
382 // side normal: RIGHT of the heading in NED (x north, y east) is (-uy, ux)
383 const float side = turnSign(p.firstTurn);
384 const float nx = -uy * side;
385 const float ny = ux * side;
386
387 const int lanes = flightPatternLawnmowerLaneCount(p);
388 const float spacing = std::max(p.laneSpacing, 0.5f);
389 const float length = std::max(p.laneLength, 0.0f);
390 const float coveredWidth = (lanes - 1) * spacing;
391
392 float ox = pick(p.originX, current.x);
393 float oy = pick(p.originY, current.y);
394 if (p.originIsCenter)
395 {
396 ox -= 0.5f * length * ux + 0.5f * coveredWidth * nx;
397 oy -= 0.5f * length * uy + 0.5f * coveredWidth * ny;
398 }
399
400 std::vector<NedPoint> path;
401 path.reserve(static_cast<size_t>(2 * lanes));
402 for (int i = 0; i < lanes; ++i)
403 {
404 NedPoint a;
405 a.x = ox + i * spacing * nx;
406 a.y = oy + i * spacing * ny;
407 a.z = z;
408 NedPoint b;
409 b.x = a.x + length * ux;
410 b.y = a.y + length * uy;
411 b.z = z;
412 if (i % 2 == 0)
413 {
414 path.push_back(a);
415 path.push_back(b);
416 }
417 else
418 {
419 path.push_back(b);
420 path.push_back(a);
421 }
422 }
423 return path;
424}

References cl_px4_mr::FlightPatternLawnmowerParams::altitudeAgl, cl_px4_mr::FlightPatternLawnmowerParams::firstTurn, flightPatternLawnmowerLaneCount(), cl_px4_mr::FlightPatternLawnmowerParams::laneHeading, cl_px4_mr::FlightPatternLawnmowerParams::laneLength, cl_px4_mr::FlightPatternLawnmowerParams::laneSpacing, cl_px4_mr::FlightPatternLawnmowerParams::originIsCenter, cl_px4_mr::FlightPatternLawnmowerParams::originX, cl_px4_mr::FlightPatternLawnmowerParams::originY, turnSign(), cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, cl_px4_mr::NedPoint::yaw, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbLawnmower::buildPath(), and generateFlightPatternGridPattern().

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

◆ generateFlightPatternLoiter()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternLoiter ( const FlightPatternLoiterParams & p,
const NedPoint & current )

Definition at line 51 of file pattern_generators.cpp.

53{
54 const float cx = pick(p.centerX, current.x);
55 const float cy = pick(p.centerY, current.y);
56 const float z = altitudeToZ(p.altitudeAgl, current.z);
57 const float r = std::max(p.radius, 0.5f);
58 const int n = std::max(p.pointsPerCircle, 8);
59 const float sign = turnSign(p.direction);
60
61 if (p.count <= 0)
62 {
63 // nothing to fly: hold the entry point (the follower posts success at once)
64 NedPoint here = current;
65 here.z = z;
66 here.yaw = kNaN;
67 return {here};
68 }
69 const int count = p.count;
70
71 // enter at the point of the circle nearest the vehicle; if at the centre
72 // use the entry heading to pick a start
73 const float dx = current.x - cx;
74 const float dy = current.y - cy;
75 float theta0 =
76 std::hypot(dx, dy) > 0.1f ? std::atan2(dy, dx) : (std::isnan(current.yaw) ? 0.0f : current.yaw);
77
78 std::vector<NedPoint> path;
79 path.reserve(static_cast<size_t>(count * n + 1));
80 for (int k = 0; k <= count * n; ++k)
81 {
82 const float theta = theta0 + sign * 2.0f * static_cast<float>(M_PI) * k / n;
83 NedPoint v;
84 v.x = cx + r * std::cos(theta);
85 v.y = cy + r * std::sin(theta);
86 v.z = z;
87 v.yaw = p.faceCenter ? std::atan2(cy - v.y, cx - v.x) : kNaN;
88 path.push_back(v);
89 }
90 return path;
91}

References cl_px4_mr::FlightPatternLoiterParams::altitudeAgl, cl_px4_mr::FlightPatternLoiterParams::centerX, cl_px4_mr::FlightPatternLoiterParams::centerY, cl_px4_mr::FlightPatternLoiterParams::count, cl_px4_mr::FlightPatternLoiterParams::direction, cl_px4_mr::FlightPatternLoiterParams::faceCenter, cl_px4_mr::FlightPatternLoiterParams::pointsPerCircle, cl_px4_mr::FlightPatternLoiterParams::radius, turnSign(), cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, cl_px4_mr::NedPoint::yaw, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbLoiter::buildPath().

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

◆ generateFlightPatternSineWaveHorizontal()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternSineWaveHorizontal ( const FlightPatternSineWaveHorizontalParams & p,
const NedPoint & current )

Definition at line 221 of file pattern_generators.cpp.

223{
224 const float endX = pick(p.endX, current.x);
225 const float endY = pick(p.endY, current.y);
226 const float z = altitudeToZ(p.altitudeAgl, current.z);
227 const float lambda = std::max(p.wavelength, 0.1f);
228 const float spacing = std::max(p.sampleSpacing, 0.1f);
229 const Leg leg = legFrom(current, endX, endY);
230
231 std::vector<NedPoint> path;
232 if (leg.length <= 1e-3f)
233 {
234 path.push_back(NedPoint{endX, endY, z, kNaN});
235 return path;
236 }
237
238 // left-of-track normal in NED (x north, y east): rotate u by -90 deg
239 const float nx = leg.uy;
240 const float ny = -leg.ux;
241
242 const int n = static_cast<int>(std::floor(leg.length / spacing));
243 path.reserve(static_cast<size_t>(n + 2));
244 for (int k = 0; k < n; ++k)
245 {
246 const float s = k * spacing;
247 const float offset = p.amplitude * std::sin(2.0f * static_cast<float>(M_PI) * s / lambda);
248 NedPoint v;
249 v.x = current.x + s * leg.ux + offset * nx;
250 v.y = current.y + s * leg.uy + offset * ny;
251 v.z = z;
252 path.push_back(v);
253 }
254 path.push_back(NedPoint{endX, endY, z, kNaN});
255 return path;
256}

References cl_px4_mr::FlightPatternSineWaveHorizontalParams::altitudeAgl, cl_px4_mr::FlightPatternSineWaveHorizontalParams::amplitude, cl_px4_mr::FlightPatternSineWaveHorizontalParams::endX, cl_px4_mr::FlightPatternSineWaveHorizontalParams::endY, cl_px4_mr::FlightPatternSineWaveHorizontalParams::sampleSpacing, cl_px4_mr::FlightPatternSineWaveHorizontalParams::wavelength, cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbSineWaveHorizontal::buildPath().

Here is the caller graph for this function:

◆ generateFlightPatternSineWaveVertical()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternSineWaveVertical ( const FlightPatternSineWaveVerticalParams & p,
const NedPoint & current )

Definition at line 189 of file pattern_generators.cpp.

191{
192 const float endX = pick(p.endX, current.x);
193 const float endY = pick(p.endY, current.y);
194 const float zBase = altitudeToZ(p.baseAltitudeAgl, current.z);
195 const float lambda = std::max(p.wavelength, 0.1f);
196 const float spacing = std::max(p.sampleSpacing, 0.1f);
197 const Leg leg = legFrom(current, endX, endY);
198
199 std::vector<NedPoint> path;
200 if (leg.length <= 1e-3f)
201 {
202 path.push_back(NedPoint{endX, endY, zBase, kNaN});
203 return path;
204 }
205
206 const int n = static_cast<int>(std::floor(leg.length / spacing));
207 path.reserve(static_cast<size_t>(n + 2));
208 for (int k = 0; k < n; ++k)
209 {
210 const float s = k * spacing;
211 NedPoint v;
212 v.x = current.x + s * leg.ux;
213 v.y = current.y + s * leg.uy;
214 v.z = zBase - p.amplitude * std::sin(2.0f * static_cast<float>(M_PI) * s / lambda);
215 path.push_back(v);
216 }
217 path.push_back(NedPoint{endX, endY, zBase, kNaN});
218 return path;
219}

References cl_px4_mr::FlightPatternSineWaveVerticalParams::amplitude, cl_px4_mr::FlightPatternSineWaveVerticalParams::baseAltitudeAgl, cl_px4_mr::FlightPatternSineWaveVerticalParams::endX, cl_px4_mr::FlightPatternSineWaveVerticalParams::endY, cl_px4_mr::FlightPatternSineWaveVerticalParams::sampleSpacing, cl_px4_mr::FlightPatternSineWaveVerticalParams::wavelength, cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbSineWaveVertical::buildPath().

Here is the caller graph for this function:

◆ generateFlightPatternSpiral()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternSpiral ( const FlightPatternSpiralParams & p,
const NedPoint & current )

Definition at line 307 of file pattern_generators.cpp.

309{
310 const float cx = pick(p.centerX, current.x);
311 const float cy = pick(p.centerY, current.y);
312 const float z = altitudeToZ(p.altitudeAgl, current.z);
313 const float spacing = std::max(p.spacing, 0.5f);
314 const float a = spacing / (2.0f * static_cast<float>(M_PI)); // r = a * theta
315 const float rStart = std::max(p.startRadius, 0.0f);
316 const float rEnd = std::max(p.endRadius, rStart);
317 const float sign = turnSign(p.direction);
318 const float ds = std::max(p.sampleSpacing, 0.1f);
319
320 // angular origin: bearing of the vehicle from the centre, else entry heading
321 const float dx = current.x - cx;
322 const float dy = current.y - cy;
323 const float theta0 =
324 std::hypot(dx, dy) > 0.1f ? std::atan2(dy, dx) : (std::isnan(current.yaw) ? 0.0f : current.yaw);
325
326 const float thetaStart = rStart / a;
327 const float thetaEnd = rEnd / a;
328
329 std::vector<NedPoint> path;
330 float theta = thetaStart;
331 while (theta < thetaEnd)
332 {
333 const float r = a * theta;
334 NedPoint v;
335 v.x = cx + r * std::cos(theta0 + sign * theta);
336 v.y = cy + r * std::sin(theta0 + sign * theta);
337 v.z = z;
338 path.push_back(v);
339 theta += ds / std::max(r, a); // constant arc-length steps
340 }
341 NedPoint last;
342 last.x = cx + rEnd * std::cos(theta0 + sign * thetaEnd);
343 last.y = cy + rEnd * std::sin(theta0 + sign * thetaEnd);
344 last.z = z;
345 path.push_back(last);
346
347 if (p.inward)
348 {
349 std::reverse(path.begin(), path.end());
350 }
351 return path;
352}

References cl_px4_mr::FlightPatternSpiralParams::altitudeAgl, cl_px4_mr::FlightPatternSpiralParams::centerX, cl_px4_mr::FlightPatternSpiralParams::centerY, cl_px4_mr::FlightPatternSpiralParams::direction, cl_px4_mr::FlightPatternSpiralParams::endRadius, cl_px4_mr::FlightPatternSpiralParams::inward, cl_px4_mr::FlightPatternSpiralParams::sampleSpacing, cl_px4_mr::FlightPatternSpiralParams::spacing, cl_px4_mr::FlightPatternSpiralParams::startRadius, turnSign(), cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, cl_px4_mr::NedPoint::yaw, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbSpiral::buildPath().

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

◆ generateFlightPatternSquareSpiral()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternSquareSpiral ( const FlightPatternSquareSpiralParams & p,
const NedPoint & current )

Definition at line 258 of file pattern_generators.cpp.

260{
261 const float ox = pick(p.originX, current.x);
262 const float oy = pick(p.originY, current.y);
263 const float z = altitudeToZ(p.altitudeAgl, current.z);
264 const float spacing = std::max(p.spacing, 0.5f);
265 const float sign = turnSign(p.direction);
266 float heading = pick(p.initialHeading, std::isnan(current.yaw) ? 0.0f : current.yaw);
267
268 std::vector<NedPoint> path;
269 path.reserve(static_cast<size_t>(std::max(p.numLegs, 0) + 1));
270 NedPoint v;
271 v.x = ox;
272 v.y = oy;
273 v.z = z;
274 path.push_back(v);
275
276 for (int i = 0; i < p.numLegs; ++i)
277 {
278 const float len = spacing * static_cast<float>(i / 2 + 1);
279 if (p.maxLegLength > 0.0f && len > p.maxLegLength)
280 {
281 break;
282 }
283 v.x += len * std::cos(heading);
284 v.y += len * std::sin(heading);
285 path.push_back(v);
286 heading += sign * static_cast<float>(M_PI) / 2.0f;
287 }
288 return path;
289}

References cl_px4_mr::FlightPatternSquareSpiralParams::altitudeAgl, cl_px4_mr::FlightPatternSquareSpiralParams::direction, cl_px4_mr::FlightPatternSquareSpiralParams::initialHeading, cl_px4_mr::FlightPatternSquareSpiralParams::maxLegLength, cl_px4_mr::FlightPatternSquareSpiralParams::numLegs, cl_px4_mr::FlightPatternSquareSpiralParams::originX, cl_px4_mr::FlightPatternSquareSpiralParams::originY, cl_px4_mr::FlightPatternSquareSpiralParams::spacing, turnSign(), cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, cl_px4_mr::NedPoint::yaw, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbSquareSpiral::buildPath().

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

◆ generateFlightPatternVSSearch()

std::vector< NedPoint > cl_px4_mr::generateFlightPatternVSSearch ( const FlightPatternVSSearchParams & p,
const NedPoint & current )

Definition at line 485 of file pattern_generators.cpp.

487{
488 const float dx = pick(p.datumX, current.x);
489 const float dy = pick(p.datumY, current.y);
490 const float z = altitudeToZ(p.altitudeAgl, current.z);
491 const float r = std::max(p.radius, 1.0f);
492 const float sign = turnSign(p.direction);
493 const float h0 = pick(p.initialHeading, std::isnan(current.yaw) ? 0.0f : current.yaw);
494 const int cycles = std::max(p.cycles, 1);
495
496 // leg headings in units of 120 degrees relative to the cycle's base heading:
497 // legs 3->4 and 6->7 continue straight through the datum
498 static const int kSteps[9] = {0, 1, 2, 2, 0, 1, 1, 2, 0};
499 const float third = 2.0f * static_cast<float>(M_PI) / 3.0f;
500
501 std::vector<NedPoint> path;
502 path.reserve(static_cast<size_t>(9 * cycles + 1));
503 NedPoint v;
504 v.x = dx;
505 v.y = dy;
506 v.z = z;
507 path.push_back(v);
508
509 for (int c = 0; c < cycles; ++c)
510 {
511 const float base = h0 + sign * p.reorientation * static_cast<float>(c);
512 for (int leg = 0; leg < 9; ++leg)
513 {
514 const float heading = base + sign * third * static_cast<float>(kSteps[leg]);
515 v.x += r * std::cos(heading);
516 v.y += r * std::sin(heading);
517 path.push_back(v);
518 }
519 // snap back onto the datum to cancel accumulated float drift
520 path.back().x = dx;
521 path.back().y = dy;
522 }
523 return path;
524}

References cl_px4_mr::FlightPatternVSSearchParams::altitudeAgl, cl_px4_mr::FlightPatternVSSearchParams::cycles, cl_px4_mr::FlightPatternVSSearchParams::datumX, cl_px4_mr::FlightPatternVSSearchParams::datumY, cl_px4_mr::FlightPatternVSSearchParams::direction, cl_px4_mr::FlightPatternVSSearchParams::initialHeading, cl_px4_mr::FlightPatternVSSearchParams::radius, cl_px4_mr::FlightPatternVSSearchParams::reorientation, turnSign(), cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, cl_px4_mr::NedPoint::yaw, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbVSSearch::buildPath().

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

◆ haversineDistance() [1/2]

double cl_px4_mr::haversineDistance ( const GeoPoint & a,
const GeoPoint & b )
inline

Definition at line 169 of file geo_utils.hpp.

170{
171 return haversineDistance(a.lat, a.lon, b.lat, b.lon);
172}
double haversineDistance(double lat1, double lon1, double lat2, double lon2)

References haversineDistance(), cl_px4_mr::GeoPoint::lat, and cl_px4_mr::GeoPoint::lon.

Here is the call graph for this function:

◆ haversineDistance() [2/2]

double cl_px4_mr::haversineDistance ( double lat1,
double lon1,
double lat2,
double lon2 )
inline

Definition at line 156 of file geo_utils.hpp.

157{
158 const double p1 = geo_detail::radians(lat1);
159 const double p2 = geo_detail::radians(lat2);
160 const double dLat = p2 - p1;
161 const double dLon = geo_detail::radians(lon2 - lon1);
162
163 const double a = std::sin(dLat / 2.0) * std::sin(dLat / 2.0) +
164 std::sin(dLon / 2.0) * std::sin(dLon / 2.0) * std::cos(p1) * std::cos(p2);
165 const double c = 2.0 * std::atan2(std::sqrt(a), std::sqrt(1.0 - a));
166 return kEarthRadiusM * c;
167}
constexpr double kEarthRadiusM
Definition geo_utils.hpp:59

References kEarthRadiusM, and cl_px4_mr::geo_detail::radians().

Referenced by haversineDistance().

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

◆ initialBearing()

double cl_px4_mr::initialBearing ( double lat1,
double lon1,
double lat2,
double lon2 )
inline

Definition at line 176 of file geo_utils.hpp.

177{
178 const double p1 = geo_detail::radians(lat1);
179 const double p2 = geo_detail::radians(lat2);
180 const double dLon = geo_detail::radians(lon2 - lon1);
181
182 const double y = std::sin(dLon) * std::cos(p2);
183 const double x = std::cos(p1) * std::sin(p2) - std::sin(p1) * std::cos(p2) * std::cos(dLon);
184 return std::atan2(y, x);
185}

References cl_px4_mr::geo_detail::radians().

Here is the call graph for this function:

◆ legHeading()

float cl_px4_mr::legHeading ( const NedPoint & from,
const NedPoint & to )
inline

Definition at line 239 of file pattern_generators.hpp.

240{
241 return std::atan2(to.y - from.y, to.x - from.x);
242}

References cl_px4_mr::NedPoint::x, and cl_px4_mr::NedPoint::y.

Referenced by cl_px4_mr::CbSineWaveHorizontal::buildPath().

Here is the caller graph for this function:

◆ levelRotationFromPx4Quaternion()

void cl_px4_mr::levelRotationFromPx4Quaternion ( const std::array< float, 4 > & q,
std::array< float, 9 > & r )
inline

Definition at line 30 of file level_frame.hpp.

31{
32 // px4_ros_com frame_transforms constants (tf2 order x, y, z, w)
33 const tf2::Quaternion kNedEnuQ(0.70710678118654752, 0.70710678118654752, 0.0, 0.0);
34 const tf2::Quaternion kFrdFluQ(1.0, 0.0, 0.0, 0.0);
35 const tf2::Quaternion qNedFrd(q[1], q[2], q[3], q[0]);
36 tf2::Quaternion qEnuFlu = kNedEnuQ * qNedFrd * kFrdFluQ;
37 qEnuFlu.normalize();
38 const tf2::Matrix3x3 m(qEnuFlu);
39 const double yaw = std::atan2(m[1][0], m[0][0]);
40 tf2::Matrix3x3 unyaw;
41 unyaw.setRPY(0.0, 0.0, -yaw);
42 const tf2::Matrix3x3 level = unyaw * m;
43 for (int i = 0; i < 3; ++i)
44 {
45 for (int j = 0; j < 3; ++j)
46 {
47 r[i * 3 + j] = static_cast<float>(level[i][j]);
48 }
49 }
50}

Referenced by cl_px4_mr::CpTunnelCentering::onCloud().

Here is the caller graph for this function:

◆ nedDistance()

float cl_px4_mr::nedDistance ( const NedPoint & a,
const NedPoint & b )
inline

Definition at line 188 of file geo_utils.hpp.

189{
190 const float dx = b.x - a.x;
191 const float dy = b.y - a.y;
192 const float dz = b.z - a.z;
193 return std::sqrt(dx * dx + dy * dy + dz * dz);
194}

References cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, and cl_px4_mr::NedPoint::z.

Referenced by cumulativeLengths(), generateFlightPatternGridPattern(), cl_px4_mr::CbPx4PathFollowerBase::onEntry(), resamplePolyline(), cl_px4_mr::CbFollowNedPath::setPath(), and cl_px4_mr::CbPx4PathFollowerBase::update().

Here is the caller graph for this function:

◆ nedDistanceXY()

float cl_px4_mr::nedDistanceXY ( const NedPoint & a,
const NedPoint & b )
inline

Definition at line 196 of file geo_utils.hpp.

197{
198 const float dx = b.x - a.x;
199 const float dy = b.y - a.y;
200 return std::sqrt(dx * dx + dy * dy);
201}

References cl_px4_mr::NedPoint::x, and cl_px4_mr::NedPoint::y.

Referenced by cl_px4_mr::CbPx4PathFollowerBase::update().

Here is the caller graph for this function:

◆ polylineLength()

float cl_px4_mr::polylineLength ( const std::vector< NedPoint > & path)
inline

Definition at line 221 of file geo_utils.hpp.

222{
223 if (path.empty())
224 {
225 return 0.0f;
226 }
227 return cumulativeLengths(path).back();
228}

References cumulativeLengths().

Here is the call graph for this function:

◆ resamplePolyline()

std::vector< NedPoint > cl_px4_mr::resamplePolyline ( const std::vector< NedPoint > & path,
float spacing )
inline

Definition at line 271 of file geo_utils.hpp.

272{
273 std::vector<NedPoint> out;
274 if (path.empty() || spacing <= 0.0f)
275 {
276 return path;
277 }
278 out.push_back(path.front());
279 for (size_t i = 1; i < path.size(); ++i)
280 {
281 const NedPoint & a = path[i - 1];
282 const NedPoint & b = path[i];
283 const float len = nedDistance(a, b);
284 const int n = std::max(1, static_cast<int>(std::ceil(len / spacing)));
285 for (int k = 1; k < n; ++k)
286 {
287 const float t = static_cast<float>(k) / static_cast<float>(n);
288 NedPoint p;
289 p.x = a.x + t * (b.x - a.x);
290 p.y = a.y + t * (b.y - a.y);
291 p.z = a.z + t * (b.z - a.z);
292 out.push_back(p);
293 }
294 out.push_back(b);
295 }
296 return out;
297}

References nedDistance(), cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, and cl_px4_mr::NedPoint::z.

Here is the call graph for this function:

◆ sampleAtArcLength()

NedPoint cl_px4_mr::sampleAtArcLength ( const std::vector< NedPoint > & path,
const std::vector< float > & cum,
float s,
size_t * segmentIndex = nullptr )
inline

Definition at line 233 of file geo_utils.hpp.

236{
237 if (path.empty())
238 {
239 return NedPoint{};
240 }
241 if (path.size() == 1 || s <= 0.0f)
242 {
243 if (segmentIndex) *segmentIndex = 0;
244 return path.front();
245 }
246 if (s >= cum.back())
247 {
248 if (segmentIndex) *segmentIndex = path.size() - 2;
249 return path.back();
250 }
251
252 // first vertex whose cumulative length exceeds s
253 auto it = std::upper_bound(cum.begin(), cum.end(), s);
254 size_t i1 = static_cast<size_t>(it - cum.begin());
255 size_t i0 = i1 - 1;
256 const float segLen = cum[i1] - cum[i0];
257 const float t = segLen > 0.0f ? (s - cum[i0]) / segLen : 0.0f;
258
259 if (segmentIndex) *segmentIndex = i0;
260
261 NedPoint p;
262 p.x = path[i0].x + t * (path[i1].x - path[i0].x);
263 p.y = path[i0].y + t * (path[i1].y - path[i0].y);
264 p.z = path[i0].z + t * (path[i1].z - path[i0].z);
265 p.yaw = path[i0].yaw; // yaw is per-vertex, not interpolated
266 return p;
267}

References cl_px4_mr::NedPoint::x, cl_px4_mr::NedPoint::y, cl_px4_mr::NedPoint::yaw, and cl_px4_mr::NedPoint::z.

Referenced by cl_px4_mr::CbPx4PathFollowerBase::commandFor().

Here is the caller graph for this function:

◆ turnName()

const char * cl_px4_mr::turnName ( Turn t)
inline

Definition at line 58 of file pattern_generators.hpp.

58{ return t == Turn::RIGHT ? "RIGHT" : "LEFT"; }

References RIGHT.

Referenced by cl_px4_mr::CbLemniscate::buildPath(), cl_px4_mr::CbLoiter::buildPath(), cl_px4_mr::CbSpiral::buildPath(), cl_px4_mr::CbSquareSpiral::buildPath(), and cl_px4_mr::CbVSSearch::buildPath().

Here is the caller graph for this function:

◆ turnSign()

float cl_px4_mr::turnSign ( Turn t)
inline

Definition at line 57 of file pattern_generators.hpp.

57{ return t == Turn::RIGHT ? 1.0f : -1.0f; }

References RIGHT.

Referenced by generateFlightPatternFigureEight(), generateFlightPatternLawnmower(), generateFlightPatternLoiter(), generateFlightPatternSpiral(), generateFlightPatternSquareSpiral(), and generateFlightPatternVSSearch().

Here is the caller graph for this function:

◆ wrapPi()

float cl_px4_mr::wrapPi ( float angle)
inline

Definition at line 25 of file angle_utils.hpp.

26{
27 angle = std::fmod(angle + static_cast<float>(M_PI), 2.0f * static_cast<float>(M_PI));
28 if (angle < 0.0f)
29 {
30 angle += 2.0f * static_cast<float>(M_PI);
31 }
32 return angle - static_cast<float>(M_PI);
33}

Referenced by cl_px4_mr::CbPx4PathFollowerBase::applyCentering(), cl_px4_mr::CbPx4PathFollowerBase::commandFor(), cl_px4_mr::CbSineAltitudeCruise::onEntry(), cl_px4_mr::CbWaitForHeadingStable::onEntry(), cl_px4_mr::CbYawScan::onEntry(), and cl_px4_mr::CbYawScan::update().

Here is the caller graph for this function:

Variable Documentation

◆ kEarthRadiusM

double cl_px4_mr::kEarthRadiusM = 6371000.0
constexpr