Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
controllers::StanleyController Class Reference

Provides an implementation of a lightweight lateral StanleyController. This algorithm is used to precisely control a different drive robot to follow a given path. More...

#include <StanleyController.h>

Public Member Functions

 StanleyController (const double dKp=1.0, const double dDistToFrontAxle=1.0, const double dYawTolerance=1.0)
 Construct a new Stanley Contoller:: Stanley Contoller object.
 
 StanleyController (const std::vector< geoops::UTMCoordinate > &vUTMPath, const double dKp, const double dDistToFrontAxle, const double dYawTolerance)
 Construct a new Stanley Contoller:: Stanley Contoller object.
 
 StanleyController (const std::vector< geoops::GPSCoordinate > &vGPSPath, const double dKp, const double dDistToFrontAxle, const double dYawTolerance)
 Construct a new Stanley Contoller:: Stanley Contoller object.
 
 ~StanleyController ()
 Destroy the Stanley Contoller:: Stanley Contoller object.
 
double Calculate (const geoops::UTMCoordinate &stUTMCurrPos, const double dVelocity, const double dCurrentHeading)
 Calculate the steering control adjustment for an agent using the Stanley method.
 
double Calculate (const geoops::GPSCoordinate &stGPSCurrPos, const double dVelocity, const double dCurrentHeading)
 Calculate the steering control adjustment for an agent using the Stanley method.
 
void ResetProgress ()
 Resets the progress on the current path.
 
void SetSteeringControlGain (const double dKpp)
 Setter for steering control gain.
 
void SetDistanceToFrontAxle (const double dDistToFrontAxle)
 Setter for distance to front axle.
 
void SetYawTolerance (const double dYawTolerance)
 Setter for yaw tolerance.
 
void SetPath (const std::vector< geoops::UTMCoordinate > &vUTMPath)
 Setter for path.
 
void SetPath (const std::vector< geoops::GPSCoordinate > &vGPSPath)
 Setter for path.
 
void SetPath (const std::vector< geoops::Waypoint > &vWaypointsPath)
 Setter for path.
 
void ClearPath ()
 Clear the current path.
 
double GetSteeringControlGain () const
 Getter for steering control gain.
 
double GetDistanceToFrontAxle () const
 Getter for distance to the front axle.
 
double GetYawTolerance () const
 Getter for yaw tolerance.
 
unsigned int GetLastTargetIdx () const
 Getter for the index of the last target point on the path.
 
std::vector< geoops::UTMCoordinateGetPathUTM () const
 Getter for path.
 
std::vector< geoops::GPSCoordinateGetPathGPS () const
 Getter for path.
 

Private Member Functions

geoops::UTMCoordinate CalculateFrontAxleCoordinate (const geoops::UTMCoordinate &stUTMCurrPos, const double dCurrentHeading) const
 Calculate the UTM coordinate of the center of the agent's front axle.
 
unsigned int IdentifyTargetIdx (const geoops::UTMCoordinate &stUTMFrontAxlePos) const
 Identifies the closest point to the center of the agent's front axle on the path.
 
double CalculateTargetBearing (const unsigned int unTargetIdx) const
 Calculate the required heading to navigate from the current target point to the subsequent point on the path.
 
double CalculateCrossTrackError (const geoops::UTMCoordinate &stUTMFrontAxlePos, const unsigned int unTargetIdx, const double dCurrentHeading) const
 Calculate the cross track error. This error expresses how far off the agent is from the path (lateral distance).
 

Private Attributes

double m_dKp
 
double m_dDistToFrontAxle
 
double m_dYawTolerance
 
unsigned int m_unLastTargetIdx
 
std::vector< geoops::UTMCoordinatem_vUTMPath
 
std::vector< geoops::GPSCoordinatem_vGPSPath
 

Detailed Description

Provides an implementation of a lightweight lateral StanleyController. This algorithm is used to precisely control a different drive robot to follow a given path.

Note
In this class heading/bearing refers to the absolute orientation of a rover (N,E,S,W). While yaw refers to an angle relative to the agent's current orientation.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-01

Constructor & Destructor Documentation

◆ StanleyController() [1/3]

controllers::StanleyController::StanleyController ( const double  dKp = 1.0,
const double  dDistToFrontAxle = 1.0,
const double  dYawTolerance = 1.0 
)

Construct a new Stanley Contoller:: Stanley Contoller object.

Parameters
dKp- Steering control gain.
dDistToFrontAxle- Distance between the position sensor (GPS) and the front axle.
dYawTolerance- Minimum yaw change threshold for execution.
Note
The higher the steering control gain the more reactive the rover will be to changes in yaw.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-03
42 {
43 // Initialize member variables
44 m_dKp = dKp;
45 m_dDistToFrontAxle = dDistToFrontAxle;
46 m_dYawTolerance = dYawTolerance;
47 m_unLastTargetIdx = 0;
48 }

◆ StanleyController() [2/3]

controllers::StanleyController::StanleyController ( const std::vector< geoops::UTMCoordinate > &  vUTMPath,
const double  dKp,
const double  dDistToFrontAxle,
const double  dYawTolerance 
)

Construct a new Stanley Contoller:: Stanley Contoller object.

Parameters
vUTMPath- Vector of UTM coordinates describing path to follow.
dKp- Steering control gain.
dDistToFrontAxle- Distance between the position sensor (GPS) and the front axle.
dYawTolerance- Minimum yaw change threshold for execution.
Note
The higher the steering control gain the more reactive the rover will be to changes in yaw.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-03
64 {
65 // Initialize member variables
66 m_dKp = dKp;
67 m_dDistToFrontAxle = dDistToFrontAxle;
68 m_dYawTolerance = dYawTolerance;
69 m_unLastTargetIdx = 0;
70 m_vUTMPath = vUTMPath;
71
72 // Convert the UTM path to a GPS path and save it.
73 m_vGPSPath.clear();
74 std::vector<geoops::UTMCoordinate>::const_iterator itrUTM = vUTMPath.begin();
75 while (itrUTM != vUTMPath.end())
76 {
77 m_vGPSPath.push_back(geoops::ConvertUTMToGPS(*itrUTM));
78 ++itrUTM;
79 }
80 }
GPSCoordinate ConvertUTMToGPS(const UTMCoordinate &stUTMCoord)
Given a UTM coordinate, convert to GPS and create a new GPSCoordinate object.
Definition GeospatialOperations.hpp:347
Here is the call graph for this function:

◆ StanleyController() [3/3]

controllers::StanleyController::StanleyController ( const std::vector< geoops::GPSCoordinate > &  vGPSPath,
const double  dKp,
const double  dDistToFrontAxle,
const double  dYawTolerance 
)

Construct a new Stanley Contoller:: Stanley Contoller object.

Parameters
vGPSPath- Vector of GPS coordinates describing path to follow.
dKp- Steering control gain.
dDistToFrontAxle- Distance between the position sensor (GPS) and the front axle.
dYawTolerance- Minimum yaw change threshold for execution.
Note
The higher the steering control gain the more reactive the rover will be to changes in yaw.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-17-03
96 {
97 // Initialize member variables
98 m_dKp = dKp;
99 m_dDistToFrontAxle = dDistToFrontAxle;
100 m_dYawTolerance = dYawTolerance;
101 m_unLastTargetIdx = 0;
102
103 // For each GPS coordinate convert it to UTM and save it to the path.
104 std::vector<geoops::GPSCoordinate>::const_iterator itrGPS = vGPSPath.begin();
105 while (itrGPS != vGPSPath.end())
106 {
107 m_vUTMPath.push_back(geoops::ConvertGPSToUTM(*itrGPS));
108 ++itrGPS;
109 }
110 m_vGPSPath = vGPSPath;
111 }
UTMCoordinate ConvertGPSToUTM(const GPSCoordinate &stGPSCoord)
Given a GPS coordinate, convert to UTM and create a new UTMCoordinate object.
Definition GeospatialOperations.hpp:302
Here is the call graph for this function:

◆ ~StanleyController()

controllers::StanleyController::~StanleyController ( )

Destroy the Stanley Contoller:: Stanley Contoller object.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-01
121 {
122 // Nothing to destroy yet.
123 }

Member Function Documentation

◆ Calculate() [1/2]

double controllers::StanleyController::Calculate ( const geoops::UTMCoordinate stUTMCurrPos,
const double  dVelocity,
const double  dCurrentHeading 
)

Calculate the steering control adjustment for an agent using the Stanley method.

This function computes the necessary change in yaw (steering angle) to align the agent with the predetermined path. The steering angle is limited by the proportional gain constant to prevent excessively sharp turns.

Parameters
stUTMCurrPos- The agent's current position in the UTM coordinate space.
dVelocity- The agent's current magnitude of velocity.
dCurrentHeading- The agent's current yaw angle (heading).
Returns
double - The calculated change in yaw needed to align the agent with the path.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-03
140 {
141 // Verify the given heading is within 0-360 degrees.
142 if (dCurrentHeading < 0 || dCurrentHeading > 360)
143 {
144 LOG_ERROR(logging::g_qSharedLogger, "Heading must be in the interval [0-360]. Received: {}", dCurrentHeading);
145 return 0;
146 }
147 // Verify a path has been loaded into the Stanley Controller
148 if (m_vUTMPath.empty())
149 {
150 LOG_ERROR(logging::g_qSharedLogger, "No path has been loaded.");
151 return 0;
152 }
153
154 // Calculate the position for the center of the front axle.
155 geoops::UTMCoordinate stUTMFrontAxlePos = CalculateFrontAxleCoordinate(stUTMCurrPos, dCurrentHeading);
156
157 // Find the point on the path closest to the front axle center
158 unsigned int unTargetIdx = IdentifyTargetIdx(stUTMFrontAxlePos);
159
160 // Make sure the agent proceeds forward through the path
161 unTargetIdx = std::max(unTargetIdx, m_unLastTargetIdx);
162 m_unLastTargetIdx = unTargetIdx;
163
164 // Calculate the change in yaw needed to go from the target to the next point
165 double dTargetYaw = CalculateTargetBearing(unTargetIdx);
166
167 // Calculate the difference between the rover's yaw and the desired path yaw
168 double dYawError = numops::InputAngleModulus<double>(dTargetYaw - dCurrentHeading, -180.0, 180.0);
169
170 // Calculate the change in yaw needed to correct for the cross track error
171 double dCrossTrackError = CalculateCrossTrackError(stUTMFrontAxlePos, unTargetIdx, dCurrentHeading);
172 double dDeltaYaw = dYawError + std::atan2(m_dKp * dCrossTrackError, dVelocity);
173
174 // If a rotation is small enough we will just go ahead and skip it
175 if (std::abs(dDeltaYaw) < m_dYawTolerance)
176 {
177 dDeltaYaw = 0;
178 }
179
180 // Here we translate the relative change in yaw to an absolute heading
181 return numops::InputAngleModulus<double>(dCurrentHeading + dDeltaYaw, 0, 360);
182 }
geoops::UTMCoordinate CalculateFrontAxleCoordinate(const geoops::UTMCoordinate &stUTMCurrPos, const double dCurrentHeading) const
Calculate the UTM coordinate of the center of the agent's front axle.
Definition StanleyController.cpp:434
double CalculateTargetBearing(const unsigned int unTargetIdx) const
Calculate the required heading to navigate from the current target point to the subsequent point on t...
Definition StanleyController.cpp:504
unsigned int IdentifyTargetIdx(const geoops::UTMCoordinate &stUTMFrontAxlePos) const
Identifies the closest point to the center of the agent's front axle on the path.
Definition StanleyController.cpp:469
double CalculateCrossTrackError(const geoops::UTMCoordinate &stUTMFrontAxlePos, const unsigned int unTargetIdx, const double dCurrentHeading) const
Calculate the cross track error. This error expresses how far off the agent is from the path (lateral...
Definition StanleyController.cpp:558
This struct stores/contains information about a UTM coordinate.
Definition GeospatialOperations.hpp:195
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Calculate() [2/2]

double controllers::StanleyController::Calculate ( const geoops::GPSCoordinate stGPSCurrPos,
const double  dVelocity,
const double  dCurrentHeading 
)

Calculate the steering control adjustment for an agent using the Stanley method.

This function computes the necessary change in yaw (steering angle) to align the agent with the predetermined path. The steering angle is limited by the proportional gain constant to prevent excessively sharp turns.

Parameters
stGPSCurrPos- The agent's current position in the GPS coordinate space.
dVelocity- The agent's current magnitude of velocity.
dCurrentHeading- The agent's current yaw angle (heading).
Returns
double - The calculated change in yaw needed to align the agent with the path.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-17
199 {
200 geoops::UTMCoordinate stUTMCurrPos = geoops::ConvertGPSToUTM(stGPSCurrPos);
201 return Calculate(stUTMCurrPos, dVelocity, dCurrentHeading);
202 }
double Calculate(const geoops::UTMCoordinate &stUTMCurrPos, const double dVelocity, const double dCurrentHeading)
Calculate the steering control adjustment for an agent using the Stanley method.
Definition StanleyController.cpp:139
Here is the call graph for this function:

◆ ResetProgress()

void controllers::StanleyController::ResetProgress ( )

Resets the progress on the current path.

The stanley control algorithm prevents points that have been pass to be revisited to motivate the agent to go further along the path. Although sometimes it may be necessary to restart an agents progress if it deviates far enough from the path.

Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
216 {
217 m_unLastTargetIdx = 0;
218 }
Here is the caller graph for this function:

◆ SetSteeringControlGain()

void controllers::StanleyController::SetSteeringControlGain ( const double  dKp)

Setter for steering control gain.

Parameters
dKp- Steering control gain.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
229 {
230 m_dKp = dKp;
231 }

◆ SetDistanceToFrontAxle()

void controllers::StanleyController::SetDistanceToFrontAxle ( const double  dDistToFrontAxle)

Setter for distance to front axle.

Parameters
dDistToFrontAxle- Distance between the position sensor (GPS) and the front axle.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
242 {
243 m_dDistToFrontAxle = dDistToFrontAxle;
244 }

◆ SetYawTolerance()

void controllers::StanleyController::SetYawTolerance ( const double  dYawTolerance)

Setter for yaw tolerance.

Parameters
dYawTolerance- Minimum yaw change threshold for execution.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
255 {
256 m_dYawTolerance = dYawTolerance;
257 }

◆ SetPath() [1/3]

void controllers::StanleyController::SetPath ( const std::vector< geoops::UTMCoordinate > &  vUTMPath)

Setter for path.

Parameters
vUTMPath- Vector of UTM coordinates describing path to follow.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
268 {
269 m_vUTMPath = vUTMPath;
270 m_unLastTargetIdx = 0;
271
272 // Convert the UTM path to a GPS path and save it.
273 m_vGPSPath.clear();
274 std::vector<geoops::UTMCoordinate>::const_iterator itrUTM = vUTMPath.begin();
275 while (itrUTM != vUTMPath.end())
276 {
277 m_vGPSPath.push_back(geoops::ConvertUTMToGPS(*itrUTM));
278 ++itrUTM;
279 }
280 }
Here is the call graph for this function:

◆ SetPath() [2/3]

void controllers::StanleyController::SetPath ( const std::vector< geoops::GPSCoordinate > &  vGPSPath)

Setter for path.

Parameters
vGPSPath- Vector of GPS coordinates describing path to follow.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-17
291 {
292 m_vUTMPath.clear();
293
294 // For each GPS coordinate convert it to UTM and save it to the path.
295 std::vector<geoops::GPSCoordinate>::const_iterator itrGPS = vGPSPath.begin();
296 while (itrGPS != vGPSPath.end())
297 {
298 m_vUTMPath.push_back(geoops::ConvertGPSToUTM(*itrGPS));
299 ++itrGPS;
300 }
301 m_vGPSPath = vGPSPath;
302
303 m_unLastTargetIdx = 0;
304 }
Here is the call graph for this function:

◆ SetPath() [3/3]

void controllers::StanleyController::SetPath ( const std::vector< geoops::Waypoint > &  vWaypointsPath)

Setter for path.

Parameters
vWaypointsPath- Vector of waypoints describing path to follow.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-07
315 {
316 // Clear the current paths.
317 m_vUTMPath.clear();
318 m_vGPSPath.clear();
319
320 // For each GPS coordinate convert it to UTM and save it to the path.
321 std::vector<geoops::Waypoint>::const_iterator itrWaypoint = vWaypointsPath.begin();
322 while (itrWaypoint != vWaypointsPath.end())
323 {
324 m_vUTMPath.push_back(itrWaypoint->GetUTMCoordinate());
325 m_vGPSPath.push_back(itrWaypoint->GetGPSCoordinate());
326 ++itrWaypoint;
327 }
328
329 // Reset the last target index.
330 m_unLastTargetIdx = 0;
331 }

◆ ClearPath()

void controllers::StanleyController::ClearPath ( )

Clear the current path.

Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-07
419 {
420 m_vUTMPath.clear();
421 m_vGPSPath.clear();
422 }

◆ GetSteeringControlGain()

double controllers::StanleyController::GetSteeringControlGain ( ) const

Getter for steering control gain.

Returns
double - Steering control gain.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
342 {
343 return m_dKp;
344 }

◆ GetDistanceToFrontAxle()

double controllers::StanleyController::GetDistanceToFrontAxle ( ) const

Getter for distance to the front axle.

Returns
double - Distance between the position sensor (GPS) and the front axle.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
355 {
356 return m_dDistToFrontAxle;
357 }

◆ GetYawTolerance()

double controllers::StanleyController::GetYawTolerance ( ) const

Getter for yaw tolerance.

Returns
double - Minimum yaw change threshold for execution.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
368 {
369 return m_dYawTolerance;
370 }

◆ GetLastTargetIdx()

unsigned int controllers::StanleyController::GetLastTargetIdx ( ) const

Getter for the index of the last target point on the path.

Returns
unsigned int - Index of the last target point on the path.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
381 {
382 return m_unLastTargetIdx;
383 }
Here is the caller graph for this function:

◆ GetPathUTM()

std::vector< geoops::UTMCoordinate > controllers::StanleyController::GetPathUTM ( ) const

Getter for path.

Returns
std::vector<geoops::UTMCoordinate> - Sequence of UTM coordinates defining the navigational path.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-16
394 {
395 return m_vUTMPath;
396 }

◆ GetPathGPS()

std::vector< geoops::GPSCoordinate > controllers::StanleyController::GetPathGPS ( ) const

Getter for path.

Returns
std::vector<geoops::GPSCoordinate> - Sequence of GPS coordinates defining the navigational path.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-17
407 {
408 return m_vGPSPath;
409 }

◆ CalculateFrontAxleCoordinate()

geoops::UTMCoordinate controllers::StanleyController::CalculateFrontAxleCoordinate ( const geoops::UTMCoordinate stUTMCurrPos,
const double  dCurrentHeading 
) const
private

Calculate the UTM coordinate of the center of the agent's front axle.

Parameters
stUTMCurrPos- The agent's current position in the UTM coordinate space.
dCurrentHeading- The current heading of the agent, measured in degrees from 0 to 360.
Returns
UTMCoordinate - The UTM coordinate of the center of the agent's front axle.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-08
435 {
436 // Convert the heading to a change in degrees of yaw relative to the north axis
437 // Here a positive degree represents a change in yaw towards the East.
438 // Here a negative degree represents a change in yaw towards the West.
439 double dChangeInYawRelToNorth = dCurrentHeading <= 180 ? dCurrentHeading : dCurrentHeading - 360;
440
441 // Convert to radians.
442 dChangeInYawRelToNorth = (dChangeInYawRelToNorth / 180) * M_PI;
443
444 // Calculate the unit vector for the agent's orientation in terms of East and North.
445 double dOrientEast = std::sin(dChangeInYawRelToNorth);
446 double dOrientNorth = std::cos(dChangeInYawRelToNorth);
447
448 // Calculate the UTM coordinate for the center of the agent's front axle.
449 geoops::UTMCoordinate stUTMFrontAxlePos = geoops::UTMCoordinate(stUTMCurrPos);
450 stUTMFrontAxlePos.dEasting = stUTMCurrPos.dEasting + m_dDistToFrontAxle * dOrientEast;
451 stUTMFrontAxlePos.dNorthing = stUTMCurrPos.dNorthing + m_dDistToFrontAxle * dOrientNorth;
452
453 // Return the UTM coordinate of the center of the agent's front axle.
454 return stUTMFrontAxlePos;
455 }
Here is the caller graph for this function:

◆ IdentifyTargetIdx()

unsigned int controllers::StanleyController::IdentifyTargetIdx ( const geoops::UTMCoordinate stUTMFrontAxlePos) const
private

Identifies the closest point to the center of the agent's front axle on the path.

This function scans through a set of path points to find the one that is nearest to the center of the agent's front axle, providing a crucial reference for any path corrections.

Parameters
stUTMFrontAxlePos- The UTM coordinate of the center of the agent's front axle.
Returns
unsigned int - Index of the target point on the path.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-03
470 {
471 // Search for the nearest point in the path
472 unsigned int unTargetIdx = 0;
473 double dMinDistance = std::numeric_limits<double>::max();
474 std::vector<geoops::UTMCoordinate>::const_iterator itPath = this->m_vUTMPath.begin();
475 while (itPath != this->m_vUTMPath.end())
476 {
477 // Find the distance in meters between the center of the front axle and a point on the path.
478 double dDistanceFromPoint = std::hypot(stUTMFrontAxlePos.dNorthing - itPath->dNorthing, stUTMFrontAxlePos.dEasting - itPath->dEasting);
479
480 // Update the closest point to the front axle's center if the current distance is the shortest recorded.
481 // Save both the point's index and the distance.
482 if (dDistanceFromPoint < dMinDistance)
483 {
484 unTargetIdx = std::distance(this->m_vUTMPath.begin(), itPath);
485 dMinDistance = dDistanceFromPoint;
486 }
487
488 // Move the iterator to the next point in the path
489 ++itPath;
490 }
491
492 return unTargetIdx;
493 }
Here is the caller graph for this function:

◆ CalculateTargetBearing()

double controllers::StanleyController::CalculateTargetBearing ( const unsigned int  unTargetIdx) const
private

Calculate the required heading to navigate from the current target point to the subsequent point on the path.

Parameters
unTargetIdx- Index of the target point on the path.
Returns
double - Bearing required to get from the target point to the subsequent point on the path.
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-03
505 {
506 // Verify the target index is a valid point on the path.
507 if (m_vUTMPath.empty() || unTargetIdx >= m_vUTMPath.size())
508 {
509 LOG_ERROR(logging::g_qSharedLogger, "Target index {} does not exist on path.", unTargetIdx);
510 return 0;
511 }
512
513 // The yaw is calculated by finding the heading needed to navigate from the
514 // target point to the next point in the path.
515 geoops::UTMCoordinate stUTMTargetPoint = m_vUTMPath[unTargetIdx];
516 geoops::UTMCoordinate stUTMNextPoint = m_vUTMPath[unTargetIdx + 1];
517
518 // Calculate the displacement from the target point to the next point in the path.
519 double dDisplacementEast = stUTMNextPoint.dEasting - stUTMTargetPoint.dEasting;
520 double dDisplacementNorth = stUTMNextPoint.dNorthing - stUTMTargetPoint.dNorthing;
521
522 // Calculate the magnitude of the displacement.
523 double dDisplacementMagnitude = std::hypot(dDisplacementEast, dDisplacementNorth);
524
525 // Calculate the heading in degrees required to navigate to the next point on the path.
526 dDisplacementNorth /= dDisplacementMagnitude;
527 double dCurrentHeading = (std::acos(dDisplacementNorth) / M_PI) * 180;
528 if (dDisplacementEast < 0)
529 {
530 dCurrentHeading = 360 - dCurrentHeading;
531 }
532
533 // Return the relative heading needed to get from the target point to the next point in the path.
534 return dCurrentHeading;
535 }
Here is the caller graph for this function:

◆ CalculateCrossTrackError()

double controllers::StanleyController::CalculateCrossTrackError ( const geoops::UTMCoordinate stUTMFrontAxlePos,
const unsigned int  unTargetIdx,
const double  dCurrentHeading 
) const
private

Calculate the cross track error. This error expresses how far off the agent is from the path (lateral distance).

Note
Here is what causes a high magnitude for cross track error.
  1. The agent is far from the target point (a large displacement from the path).
  2. The agent is driving parallel to the path. The reason for number 2 is if the agent is far from the path and driving parallel it will continue to stay off course. However, if the agent is on the path and driving parallel the displacement vector will be negligible and the error will likewise be negligible.
Note that the significance of the error is its magnitude. Positive and negative are the same amount of error just in opposing directions.
Parameters
stUTMFrontAxlePos- The UTM coordinate of the center of the agent's front axle.
unTargetIdx- Index of the target point on the path.
dCurrentHeading- The current heading of the agent, measured in degrees from 0 to 360.
Returns
double - The cross track error (CTE).
Author
JSpencerPittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-02-09
559 {
560 // Check if the target index is valid and the path is not empty.
561 if (m_vUTMPath.empty() || unTargetIdx >= m_vUTMPath.size())
562 {
563 LOG_ERROR(logging::g_qSharedLogger, "Target index {} does not exist on path.", unTargetIdx);
564 return 0;
565 }
566
567 // Convert the heading to a change in degrees of yaw relative to the north axis
568 // Here a positive degree represents a change in yaw towards the East.
569 // Here a negative degree represents a change in yaw towards the West.
570 double dChangeInYawRelToNorth = dCurrentHeading <= 180 ? dCurrentHeading : dCurrentHeading - 360;
571 dChangeInYawRelToNorth = (dChangeInYawRelToNorth / 180) * M_PI;
572 dChangeInYawRelToNorth -= M_PI / 2;
573
574 // Calculate the front axle vector.
575 // This vector will point perpendicular to the orientation of the agent (representing the front drive axle).
576 double dFrontDriveAxleX = std::sin(dChangeInYawRelToNorth);
577 double dFrontDriveAxleY = std::cos(dChangeInYawRelToNorth);
578
579 // Find the displacement between the target and the center of the front drive axle.
580 geoops::UTMCoordinate stUTMTargetPos = m_vUTMPath[unTargetIdx];
581 double dDisplacementX = stUTMFrontAxlePos.dEasting - stUTMTargetPos.dEasting;
582 double dDisplacementY = stUTMFrontAxlePos.dNorthing - stUTMTargetPos.dNorthing;
583
584 // Calculate the cross track error as a dot product of our front drive axle and the displacement vector.
585 return (dDisplacementX * dFrontDriveAxleX) + (dDisplacementY * dFrontDriveAxleY);
586 }
Here is the caller graph for this function:

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