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

False conflict pairs using statebased CD #345

Open
MiGiliam opened this issue Dec 2, 2021 · 1 comment
Open

False conflict pairs using statebased CD #345

MiGiliam opened this issue Dec 2, 2021 · 1 comment

Comments

@MiGiliam
Copy link
Contributor

MiGiliam commented Dec 2, 2021

Using statebased CD, false detections can occur when the following conditions apply to an aircraft pair:

  1. Altitude difference equal to the required vertical separation margin
  2. Vertical speed difference equal to zero
  3. Horizontally in conflict

Theoretically, conditions (1) and (2) imply that the aircraft are vertically not in conflict, they just stay outside the vertical boundaries of each other's protected zone. Nevertheless, a conflict is detected for the aircraft flying on the upper boundary, see the screenshot below. As a result, the list of conflict pairs includes a non-unique conflict: only (AC2, AC1), not (AC1, AC2).
Statebased_conflict_bug

Statebased conflict detection computes vertical crossing of the protected zone as follows (line 68-82):

# Vertical crossing of disk (-dh,+dh)
dalt = ownship.alt.reshape((1, ownship.ntraf)) - \
                intruder.alt.reshape((1, ownship.ntraf)).T  + 1e9 * I

dvs = ownship.vs.reshape(1, ownship.ntraf) - \
              intruder.vs.reshape(1, ownship.ntraf).T
dvs = np.where(np.abs(dvs) < 1e-6, 1e-6, dvs)  # prevent division by zero

# Check for passing through each others zone
# hPZ can differ per aircraft, get the largest value per aircraft pair
hpz = np.asarray(np.maximum(np.asmatrix(hpz), np.asmatrix(hpz).transpose()))
tcrosshi = (dalt + hpz) / -dvs
tcrosslo = (dalt - hpz) / -dvs
tinver = np.minimum(tcrosshi, tcrosslo)
toutver = np.maximum(tcrosshi, tcrosslo)

Printing these steps in the terminal reveals what happens. In the screenshot below, parameters corresponding with aircraft pair (AC1, AC2) are highlighted in green, (AC2, AC1) in red.

  1. The altitude difference dalt is positive for (AC1, AC2) and negative for (AC2, AC1)
  2. In order to prevent division by zero, the difference in vertical speed (dvs) is set to a very small positive value for both aircraft pairs
  3. Division by nonzero -dvs essentially means AC1 is slowly descending away from the lower PZ edge of AC2 (diverging). Using the same reasoning, AC2 is slowly descending into the PZ of AC1 (converging), almost instantly crossing the upper edge (tcrosshi = 1.7e-07)
  4. Since the vertical crossing interval for pair (AC2, AC1) lies in the future and overlaps with the horizontal interval, the conflict detection algorithm returns (AC2, AC1) as conflict pair. The opposite holds for (AC1, AC2), where the crossing interval lies in the past.

Statebased_print

I tried fixing this issue by setting the sign of dvs, where changed from zero to 1e-6, equal to the sign of dalt. This way, it is ensured that two aircraft with zero difference in vertical speed are always evaluated using diverging flight paths. Implementing this change appears to solve the problem. Line 74 could be changed to the following:
dvs = np.where(np.abs(dvs) < 1e-6, (np.sign(dalt)+(dalt==0)) * 1e-6, dvs) # prevent division by zero

np.sign returns (float) -1 for negative values, (float) 1 for positive values. If the value is zero, np.sign also returns zero, hence
+(dalt==0) should be added to prevent division by zero.

@MiGiliam
Copy link
Contributor Author

MiGiliam commented Dec 3, 2021

The example above with AC1 and AC2 was created using the following scenario file:

00:00:00.00>SWRAD SYM
00:00:00.00>CDMETHOD STATEBASED
00:00:00.00>CRE AC1,A319,51.888804,3.54858,0,FL100,250
00:00:00.00>CRE AC2,A319,52.002535,3.829349,270,FL110,250

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant