Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plane: Patch heading check for turn flexibility #25938

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ArduPlane/mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ class ModeLoiter : public Mode
void navigate() override;

bool isHeadingLinedUp(const Location loiterCenterLoc, const Location targetLoc);
bool isHeadingLinedUp_cd(const int32_t bearing_cd);
bool isHeadingLinedUp_cd(const int32_t bearing_cd, const int32_t initial_bearing_margin_cd = 1000);

bool allows_throttle_nudging() const override { return true; }

Expand Down
34 changes: 21 additions & 13 deletions ArduPlane/mode_loiter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,46 +40,54 @@ void ModeLoiter::update()
bool ModeLoiter::isHeadingLinedUp(const Location loiterCenterLoc, const Location targetLoc)
{
// Return true if current heading is aligned to vector to targetLoc.
// Tolerance is initially 10 degrees and grows at 10 degrees for each loiter circle completed.

if (loiterCenterLoc.get_distance(targetLoc) < 1.05f * fabsf(plane.loiter.radius)) {
/* Whenever next waypoint is within the loiter radius plus 5%,
const float targetDistanceFromCenter = loiterCenterLoc.get_distance(targetLoc);
if (targetDistanceFromCenter < 0.99f * fabsf(plane.loiter.radius)) {
/* Whenever next waypoint is within the loiter radius (damped slightly for rounding error),
maintaining loiter would prevent us from ever pointing toward the next waypoint.
Hence break out of loiter immediately
*/
return true;
}

// Bearing in centi-degrees
const int32_t bearing_cd = plane.current_loc.get_bearing_to(targetLoc);
if (targetDistanceFromCenter < 1.05f * fabsf(plane.loiter.radius)) {
/* Target Waypoint is between [radius, 1.05*radius) to center so we can
point toward the next waypoint, but there may be overshooting. Hence,
tolerance increased to 20 degrees on initial check to reduce loop-backs.
*/
return isHeadingLinedUp_cd(bearing_cd, 2000);
}
// Target waypoint is far enough from center, base margin tolerance is acceptable.
return isHeadingLinedUp_cd(bearing_cd);

}


bool ModeLoiter::isHeadingLinedUp_cd(const int32_t bearing_cd)
bool ModeLoiter::isHeadingLinedUp_cd(const int32_t bearing_cd, const int32_t initial_bearing_margin_cd)
{
// Return true if current heading is aligned to bearing_cd.
// Tolerance is initially 10 degrees and grows at 10 degrees for each loiter circle completed.
// Tolerance is initially "initial_bearing_margin_cd" and grows at 10 degrees for each loiter circle completed.

// get current heading.
const int32_t heading_cd = (wrap_360(degrees(ahrs.groundspeed_vector().angle())))*100;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not your problem, but we don't need to do the wrap here because we wrap the final calculation on 75.

Suggested change
const int32_t heading_cd = (wrap_360(degrees(ahrs.groundspeed_vector().angle())))*100;
const int32_t heading_cd = degrees(ahrs.groundspeed_vector().angle())*100;


const int32_t heading_err_cd = wrap_180_cd(bearing_cd - heading_cd);

/*
Check to see if the the plane is heading toward the land
waypoint. We use 20 degrees (+/-10 deg) of margin so that
we can handle 200 degrees/second of yaw.
Check to see if the the plane is heading toward the land waypoint.
We use 2*initial_bearing_margin_cd (+/- initial_bearing_margin_cd) so
that we can handle 20*initial_bearing_margin_cd degrees/second of yaw.

After every full circle, extend acceptance criteria to ensure
aircraft will not loop forever in case high winds are forcing
it beyond 200 deg/sec when passing the desired exit course
After every full circle, extend acceptance criteria to ensure aircraft
will not loop forever in case high winds are forcing it beyond
20*initial_bearing_margin_cd deg/sec when passing the desired exit course
*/

// Use integer division to get discrete steps
const int32_t expanded_acceptance = 1000 * (labs(plane.loiter.sum_cd) / 36000);

if (labs(heading_err_cd) <= 1000 + expanded_acceptance) {
if (labs(heading_err_cd) <= initial_bearing_margin_cd + expanded_acceptance) {
// Want to head in a straight line from _here_ to the next waypoint instead of center of loiter wp

// 0 to xtrack from center of waypoint, 1 to xtrack from tangent exit location
Expand Down
Loading