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

Namespaces

namespace  anonymous_namespace{cp_kml_mission_loader.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  CbFollowWaypoints
 
class  CbGoToLocation
 
class  CbGridPattern
 
class  CbHoldPosition
 
class  CbLand
 
class  CbLawnmower
 
class  CbLoadKmlMission
 
class  CbLoiter
 
class  CbOrbitLocation
 
class  CbPx4ClientBehaviorBase
 
class  CbPx4PathFollowerBase
 
class  CbReturnToHome
 
class  CbSineAltitudeCruise
 
class  CbSineWaveHorizontal
 
class  CbSineWaveVertical
 
class  CbSpiral
 
class  CbSpiralPattern
 
class  CbSquareSpiral
 
class  CbTakeOff
 
class  CbVSSearch
 
class  CbYawRotate
 
class  CbYawScan
 
class  ClPx4Mr
 
class  CpGoalChecker
 
class  CpKmlMissionLoader
 
class  CpMicroRosAgent
 
class  CpOffboardKeepAlive
 
class  CpTrajectorySetpoint
 
class  CpVehicleCommand
 
class  CpVehicleCommandAck
 
class  CpVehicleLocalPosition
 
class  CpVehicleStatus
 
struct  FlightPatternAscendParams
 
struct  FlightPatternGridPatternParams
 
struct  FlightPatternLawnmowerParams
 
struct  FlightPatternLoiterParams
 
struct  FlightPatternSineWaveHorizontalParams
 
struct  FlightPatternSineWaveVerticalParams
 
struct  FlightPatternSpiralParams
 
struct  FlightPatternSquareSpiralParams
 
struct  FlightPatternVSSearchParams
 
struct  GeoPoint
 
struct  KmlLoadResult
 
class  MapProjection
 
struct  NedPoint
 
struct  PathFollowerParams
 

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)
 
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 > 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 34 of file cb_px4_path_follower_base.hpp.

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

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:

◆ flightPatternGridPatternLength()

◆ flightPatternLawnmowerLaneCount()

int cl_px4_mr::flightPatternLawnmowerLaneCount ( const FlightPatternLawnmowerParams & p)

Definition at line 291 of file pattern_generators.cpp.

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

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 297 of file pattern_generators.cpp.

298{
299 const int lanes = flightPatternLawnmowerLaneCount(p);
300 return lanes * std::max(p.laneLength, 0.0f) + (lanes - 1) * std::max(p.laneSpacing, 0.5f);
301}
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 282 of file pattern_generators.cpp.

283{
284 // area between the radii divided by the track spacing
285 const float rStart = std::max(p.startRadius, 0.0f);
286 const float rEnd = std::max(p.endRadius, rStart);
287 const float spacing = std::max(p.spacing, 0.5f);
288 return static_cast<float>(M_PI) * (rEnd * rEnd - rStart * rStart) / spacing;
289}

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 219 of file pattern_generators.cpp.

220{
221 const float spacing = std::max(p.spacing, 0.5f);
222 float total = 0.0f;
223 for (int i = 0; i < p.numLegs; ++i)
224 {
225 const float len = spacing * static_cast<float>(i / 2 + 1);
226 if (p.maxLegLength > 0.0f && len > p.maxLegLength)
227 {
228 break;
229 }
230 total += len;
231 }
232 return total;
233}

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 408 of file pattern_generators.cpp.

409{
410 return 9.0f * std::max(p.radius, 1.0f) * static_cast<float>(std::max(p.cycles, 1));
411}

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 32 of file pattern_generators.cpp.

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

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:

◆ generateFlightPatternGridPattern()

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

Definition at line 363 of file pattern_generators.cpp.

365{
367 first.originIsCenter = true; // the grid is always centred on the origin
368 first.originX = pick(p.base.originX, current.x);
369 first.originY = pick(p.base.originY, current.y);
370 first.laneHeading = pick(p.base.laneHeading, std::isnan(current.yaw) ? 0.0f : current.yaw);
371
372 std::vector<NedPoint> path = generateFlightPatternLawnmower(first, current);
373 if (!p.secondPass || path.empty())
374 {
375 return path;
376 }
377
378 // second pass: rotated 90 degrees over the same rectangle; try the four
379 // start corners (heading +-90, step side left/right) and take the one that
380 // starts nearest the end of pass 1
381 const NedPoint & joint = path.back();
382 std::vector<NedPoint> best;
383 float bestDist = std::numeric_limits<float>::max();
384 for (int variant = 0; variant < 4; ++variant)
385 {
386 FlightPatternLawnmowerParams second = first;
387 second.laneLength = first.width;
388 second.width = first.laneLength;
389 second.laneHeading =
390 first.laneHeading + ((variant & 1) ? -1.0f : 1.0f) * static_cast<float>(M_PI) / 2.0f;
391 second.firstTurn = (variant & 2) ? Turn::LEFT : Turn::RIGHT;
392 std::vector<NedPoint> candidate = generateFlightPatternLawnmower(second, current);
393 if (candidate.empty())
394 {
395 continue;
396 }
397 const float d = nedDistance(joint, candidate.front());
398 if (d < bestDist)
399 {
400 bestDist = d;
401 best = std::move(candidate);
402 }
403 }
404 path.insert(path.end(), best.begin(), best.end());
405 return path;
406}
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 303 of file pattern_generators.cpp.

305{
306 const float z = altitudeToZ(p.altitudeAgl, current.z);
307 const float heading = pick(p.laneHeading, std::isnan(current.yaw) ? 0.0f : current.yaw);
308 const float ux = std::cos(heading);
309 const float uy = std::sin(heading);
310 // side normal: RIGHT of the heading in NED (x north, y east) is (-uy, ux)
311 const float side = turnSign(p.firstTurn);
312 const float nx = -uy * side;
313 const float ny = ux * side;
314
315 const int lanes = flightPatternLawnmowerLaneCount(p);
316 const float spacing = std::max(p.laneSpacing, 0.5f);
317 const float length = std::max(p.laneLength, 0.0f);
318 const float coveredWidth = (lanes - 1) * spacing;
319
320 float ox = pick(p.originX, current.x);
321 float oy = pick(p.originY, current.y);
322 if (p.originIsCenter)
323 {
324 ox -= 0.5f * length * ux + 0.5f * coveredWidth * nx;
325 oy -= 0.5f * length * uy + 0.5f * coveredWidth * ny;
326 }
327
328 std::vector<NedPoint> path;
329 path.reserve(static_cast<size_t>(2 * lanes));
330 for (int i = 0; i < lanes; ++i)
331 {
332 NedPoint a;
333 a.x = ox + i * spacing * nx;
334 a.y = oy + i * spacing * ny;
335 a.z = z;
336 NedPoint b;
337 b.x = a.x + length * ux;
338 b.y = a.y + length * uy;
339 b.z = z;
340 if (i % 2 == 0)
341 {
342 path.push_back(a);
343 path.push_back(b);
344 }
345 else
346 {
347 path.push_back(b);
348 path.push_back(a);
349 }
350 }
351 return path;
352}
float turnSign(Turn t)

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 50 of file pattern_generators.cpp.

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

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 149 of file pattern_generators.cpp.

151{
152 const float endX = pick(p.endX, current.x);
153 const float endY = pick(p.endY, current.y);
154 const float z = altitudeToZ(p.altitudeAgl, current.z);
155 const float lambda = std::max(p.wavelength, 0.1f);
156 const float spacing = std::max(p.sampleSpacing, 0.1f);
157 const Leg leg = legFrom(current, endX, endY);
158
159 std::vector<NedPoint> path;
160 if (leg.length <= 1e-3f)
161 {
162 path.push_back(NedPoint{endX, endY, z, kNaN});
163 return path;
164 }
165
166 // left-of-track normal in NED (x north, y east): rotate u by -90 deg
167 const float nx = leg.uy;
168 const float ny = -leg.ux;
169
170 const int n = static_cast<int>(std::floor(leg.length / spacing));
171 path.reserve(static_cast<size_t>(n + 2));
172 for (int k = 0; k < n; ++k)
173 {
174 const float s = k * spacing;
175 const float offset = p.amplitude * std::sin(2.0f * static_cast<float>(M_PI) * s / lambda);
176 NedPoint v;
177 v.x = current.x + s * leg.ux + offset * nx;
178 v.y = current.y + s * leg.uy + offset * ny;
179 v.z = z;
180 path.push_back(v);
181 }
182 path.push_back(NedPoint{endX, endY, z, kNaN});
183 return path;
184}

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 117 of file pattern_generators.cpp.

119{
120 const float endX = pick(p.endX, current.x);
121 const float endY = pick(p.endY, current.y);
122 const float zBase = altitudeToZ(p.baseAltitudeAgl, current.z);
123 const float lambda = std::max(p.wavelength, 0.1f);
124 const float spacing = std::max(p.sampleSpacing, 0.1f);
125 const Leg leg = legFrom(current, endX, endY);
126
127 std::vector<NedPoint> path;
128 if (leg.length <= 1e-3f)
129 {
130 path.push_back(NedPoint{endX, endY, zBase, kNaN});
131 return path;
132 }
133
134 const int n = static_cast<int>(std::floor(leg.length / spacing));
135 path.reserve(static_cast<size_t>(n + 2));
136 for (int k = 0; k < n; ++k)
137 {
138 const float s = k * spacing;
139 NedPoint v;
140 v.x = current.x + s * leg.ux;
141 v.y = current.y + s * leg.uy;
142 v.z = zBase - p.amplitude * std::sin(2.0f * static_cast<float>(M_PI) * s / lambda);
143 path.push_back(v);
144 }
145 path.push_back(NedPoint{endX, endY, zBase, kNaN});
146 return path;
147}

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 235 of file pattern_generators.cpp.

237{
238 const float cx = pick(p.centerX, current.x);
239 const float cy = pick(p.centerY, current.y);
240 const float z = altitudeToZ(p.altitudeAgl, current.z);
241 const float spacing = std::max(p.spacing, 0.5f);
242 const float a = spacing / (2.0f * static_cast<float>(M_PI)); // r = a * theta
243 const float rStart = std::max(p.startRadius, 0.0f);
244 const float rEnd = std::max(p.endRadius, rStart);
245 const float sign = turnSign(p.direction);
246 const float ds = std::max(p.sampleSpacing, 0.1f);
247
248 // angular origin: bearing of the vehicle from the centre, else entry heading
249 const float dx = current.x - cx;
250 const float dy = current.y - cy;
251 const float theta0 =
252 std::hypot(dx, dy) > 0.1f ? std::atan2(dy, dx) : (std::isnan(current.yaw) ? 0.0f : current.yaw);
253
254 const float thetaStart = rStart / a;
255 const float thetaEnd = rEnd / a;
256
257 std::vector<NedPoint> path;
258 float theta = thetaStart;
259 while (theta < thetaEnd)
260 {
261 const float r = a * theta;
262 NedPoint v;
263 v.x = cx + r * std::cos(theta0 + sign * theta);
264 v.y = cy + r * std::sin(theta0 + sign * theta);
265 v.z = z;
266 path.push_back(v);
267 theta += ds / std::max(r, a); // constant arc-length steps
268 }
269 NedPoint last;
270 last.x = cx + rEnd * std::cos(theta0 + sign * thetaEnd);
271 last.y = cy + rEnd * std::sin(theta0 + sign * thetaEnd);
272 last.z = z;
273 path.push_back(last);
274
275 if (p.inward)
276 {
277 std::reverse(path.begin(), path.end());
278 }
279 return path;
280}

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 186 of file pattern_generators.cpp.

188{
189 const float ox = pick(p.originX, current.x);
190 const float oy = pick(p.originY, current.y);
191 const float z = altitudeToZ(p.altitudeAgl, current.z);
192 const float spacing = std::max(p.spacing, 0.5f);
193 const float sign = turnSign(p.direction);
194 float heading = pick(p.initialHeading, std::isnan(current.yaw) ? 0.0f : current.yaw);
195
196 std::vector<NedPoint> path;
197 path.reserve(static_cast<size_t>(std::max(p.numLegs, 0) + 1));
198 NedPoint v;
199 v.x = ox;
200 v.y = oy;
201 v.z = z;
202 path.push_back(v);
203
204 for (int i = 0; i < p.numLegs; ++i)
205 {
206 const float len = spacing * static_cast<float>(i / 2 + 1);
207 if (p.maxLegLength > 0.0f && len > p.maxLegLength)
208 {
209 break;
210 }
211 v.x += len * std::cos(heading);
212 v.y += len * std::sin(heading);
213 path.push_back(v);
214 heading += sign * static_cast<float>(M_PI) / 2.0f;
215 }
216 return path;
217}

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 413 of file pattern_generators.cpp.

415{
416 const float dx = pick(p.datumX, current.x);
417 const float dy = pick(p.datumY, current.y);
418 const float z = altitudeToZ(p.altitudeAgl, current.z);
419 const float r = std::max(p.radius, 1.0f);
420 const float sign = turnSign(p.direction);
421 const float h0 = pick(p.initialHeading, std::isnan(current.yaw) ? 0.0f : current.yaw);
422 const int cycles = std::max(p.cycles, 1);
423
424 // leg headings in units of 120 degrees relative to the cycle's base heading:
425 // legs 3->4 and 6->7 continue straight through the datum
426 static const int kSteps[9] = {0, 1, 2, 2, 0, 1, 1, 2, 0};
427 const float third = 2.0f * static_cast<float>(M_PI) / 3.0f;
428
429 std::vector<NedPoint> path;
430 path.reserve(static_cast<size_t>(9 * cycles + 1));
431 NedPoint v;
432 v.x = dx;
433 v.y = dy;
434 v.z = z;
435 path.push_back(v);
436
437 for (int c = 0; c < cycles; ++c)
438 {
439 const float base = h0 + sign * p.reorientation * static_cast<float>(c);
440 for (int leg = 0; leg < 9; ++leg)
441 {
442 const float heading = base + sign * third * static_cast<float>(kSteps[leg]);
443 v.x += r * std::cos(heading);
444 v.y += r * std::sin(heading);
445 path.push_back(v);
446 }
447 // snap back onto the datum to cancel accumulated float drift
448 path.back().x = dx;
449 path.back().y = dy;
450 }
451 return path;
452}

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 219 of file pattern_generators.hpp.

220{
221 return std::atan2(to.y - from.y, to.x - from.x);
222}

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:

◆ 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(), 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(), and cl_px4_mr::CbPx4PathFollowerBase::update().

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::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 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::commandFor(), cl_px4_mr::CbSineAltitudeCruise::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