def resolve(dbconf): if not dbconf.swasas: return # required change in velocity dv=np.zeros((dbconf.traf.ntraf,3)) #if possible, solve conflicts once and copy results for symmetrical conflicts, #if that is not possible, solve each conflict twice, once for each A/C if not dbconf.traf.ADSBtrunc and not dbconf.traf.ADSBtransnoise: for conflict in dbconf.conflist_now: id1,id2=dbconf.ConflictToIndices(conflict) if id1 != "Fail" and id2!= "Fail": dv_eby=Eby_straight(dbconf,id1,id2) dv[id1]-=dv_eby dv[id2]+=dv_eby else: for i in range(dbconf.nconf): ac1=dbconf.idown[i] ac2=dbconf.idoth[i] id1=dbconf.traf.id.index(ac1) id2=dbconf.traf.id.index(ac2) dv_eby=Eby_straight(dbconf,id1,id2) dv[id1]-=dv_eby # now we have the change in speed vector for each aircraft. dv=np.transpose(dv) # the old speed vector, cartesian coordinates trkrad=np.radians(dbconf.traf.trk) v=np.array([np.sin(trkrad)*dbconf.traf.tas,\ np.cos(trkrad)*dbconf.traf.tas,\ dbconf.traf.vs]) # the new speed vector newv=dv+v # the new speed vector in polar coordinates newtrack=(np.arctan2(newv[0,:],newv[1,:])*180/np.pi) %360 newgs=np.sqrt(newv[0,:]**2+newv[1,:]**2) neweas=vtas2eas(newgs,dbconf.traf.alt) # Cap the velocity neweascapped=np.maximum(dbconf.vmin,np.minimum(dbconf.vmax,neweas)) # now assign in the traf class dbconf.traf.asashdg=newtrack dbconf.traf.asasspd=neweascapped dbconf.traf.asasvsp=newv[2,:] dbconf.traf.asasalt=np.sign(dbconf.traf.asasvsp)*1e5
def resolve(dbconf): if not dbconf.swasas: return # required change in velocity dv = np.zeros((dbconf.traf.ntraf,3)) #if possible, solve conflicts once and copy results for symmetrical conflicts, #if that is not possible, solve each conflict twice, once for each A/C if not dbconf.traf.ADSBtrunc and not dbconf.traf.ADSBtransnoise: for conflict in dbconf.conflist_now: id1,id2 = dbconf.ConflictToIndices(conflict) if id1 != "Fail" and id2!= "Fail": dv_eby = MVP(dbconf,id1,id2) # If the priority switch is ON (always ON for layers), it has a different meaning for Layers than for Full Mix # For layers -> Climbing and descending have highest priority if dbconf.swprio: # If aircraft 1 is cruising, and aircraft 2 is climbing -> aircraft one solves conflict horizontally if abs(dbconf.traf.vs[id1])<0.1 and dbconf.traf.vs[id2] > 0.1:#dbconf.traf.alt[id2] < dbconf.traf.aalt[id2]: dv[id1] = dv[id1] - dv_eby dv[id1][2] = 0.0 # If aircraft 2 is cruising, and aircraft 1 is climbing -> aircraft two solves conflict horizontally elif abs(dbconf.traf.vs[id2])<0.1 and dbconf.traf.vs[id1] > 0.1:#dbconf.traf.alt[id1] < dbconf.traf.aalt[id1]: dv[id2] = dv[id2] + dv_eby dv[id2][2] = 0.0 # If aircraft 1 is cruising, and aircraft 2 is descending -> aircraft 1 solves conflict horizontally elif abs(dbconf.traf.vs[id1])<0.1 and dbconf.traf.vs[id2] < -0.1:#dbconf.traf.alt[id2] > dbconf.traf.aalt[id2]: dv[id1] = dv[id1] - dv_eby dv[id1][2] = 0.0 # If aircraft 2 is cruising, and aircraft 1 is descending -> aircraft2 solves conflict horizontally elif abs(dbconf.traf.vs[id2])<0.1 and dbconf.traf.vs[id2] < -0.1: #dbconf.traf.alt[id1] > dbconf.traf.aalt[id1]: dv[id2] = dv[id2] + dv_eby dv[id2][2] = 0.0 # cruising - cruising, C/D - C/D -> solved horizontally else: dv[id1] = dv[id1] - dv_eby dv[id2] = dv[id2] + dv_eby dv[id1][2] = 0.0 dv[id2][2] = 0.0 else: dv[id1] = dv[id1] - dv_eby dv[id2] = dv[id2] + dv_eby else: for i in range(dbconf.nconf): ac1 = dbconf.idown[i] ac2 = dbconf.idoth[i] id1 = dbconf.traf.id.index(ac1) id2 = dbconf.traf.id.index(ac2) dv_eby = MVP(dbconf,id1,id2) dv[id1]= dv[id1] - dv_eby # now we have the change in speed vector for each aircraft. dv = np.transpose(dv) # the old speed vector, cartesian coordinates trkrad = np.radians(dbconf.traf.trk) v = np.array([np.sin(trkrad)*dbconf.traf.tas,\ np.cos(trkrad)*dbconf.traf.tas,\ dbconf.traf.vs]) # Restrict resolution direction based on swresodir if dbconf.swresodir == "HORIZ": dv[2,:] = 0. # the new speed vector newv = dv+v # the new speed vector in polar coordinates if dbconf.swresodir == "VERT": newtrack = (np.arctan2(v[0,:],v[1,:])*180/np.pi) %360 else: newtrack = (np.arctan2(newv[0,:],newv[1,:])*180/np.pi) %360 newgs = np.sqrt(newv[0,:]**2 + newv[1,:]**2) neweas = vtas2eas(newgs,dbconf.traf.alt) # Cap the velocity neweascapped=np.maximum(dbconf.vmin,np.minimum(dbconf.vmax,neweas)) # Cap the vertical speed vscapped = np.maximum(dbconf.vsmin,np.minimum(dbconf.vsmax,newv[2,:])) # now assign in the traf class dbconf.traf.asashdg = newtrack dbconf.traf.asasspd = veas2tas(neweascapped,dbconf.traf.alt) dbconf.traf.asasvsp = vscapped # To update asasalt, tinconf is used. tinconf is a really big value if there is # no conflict. If there is a conflict, tinconf will be between 0 and the lookahead # time. Therefore, asasalt should only be updated for those aircraft that have a # tinconf that is between 0 and the lookahead time. This is what the following code does: condition = dbconf.tinconf.min(axis=1)<dbconf.dtlookahead*1.2 # dtlookahead == tlook asasalttemp = dbconf.traf.asasvsp * dbconf.tinconf.min(axis=1) \ + dbconf.traf.alt # Condition2 ensures that aircraft do not overshoot their layer altitude # This is not being used for Full Mix MVP condition2 = dbconf.traf.alt != dbconf.traf.aalt dbconf.traf.asasalt[condition] = asasalttemp[condition] dbconf.traf.asasalt[condition2] = dbconf.traf.aalt[condition2]
def resolve(dbconf): if not dbconf.swasas: return # ------------------------------------------------------------------------- # First, perform special Conflict Detection to find which conflicts to resolve # Relative horizontal positions: p[a,b] is p from a to b qdrrel = np.radians(dbconf.qdr-dbconf.traf.trk.reshape((len(dbconf.traf.trk),1))) xrel= np.sin(qdrrel)*dbconf.dist yrel= np.cos(qdrrel)*dbconf.dist # Define the two borders: b1=np.where( yrel -np.abs(xrel) > -dbconf.dist_a ,True,False) b2=np.where( xrel**2 + (yrel-dbconf.dist_b)**2 < (dbconf.dist_a+dbconf.dist_b)**2 ,True,False) # Create conflict matrix dbconf.swconfl_dg = b1*b2*(1.-np.eye(dbconf.traf.ntraf)) # ------------------------------------------------------------------------- # Second, create a list of conflicts and aircraft indices to iterate over dgconfidxs = np.where(dbconf.swconfl_dg) dgnconf = len(dgconfidxs[0]) dgiown = dgconfidxs[0] dgioth = dgconfidxs[1] # ------------------------------------------------------------------------- # Third, create control matrix and find controls # Also, aircraft in DGconflict should follow ASAS dbconf.traf.asasactive.fill(False) controls=np.zeros((dbconf.traf.ntraf,3),dtype=np.int) for i in range(dgnconf): id1=dgiown[i] id2=dgioth[i] dbconf.traf.asasactive[id1]=True dbconf.traf.asasactive[id2]=True ctrl=Difgamehor(dbconf,id1,id2) controls[id1]+=ctrl-np.array([1,1,1]) # Now, write controls as limits in traf class # First: limit superpositioned controls to maximum values controls+=np.array([1,1,1]) maxcontrols=np.array([2,2,2]) controls=np.where(controls<0,0,controls) controls=np.where(controls>maxcontrols,maxcontrols,controls) # From indices to values acccontrol=dbconf.a_o[controls[:,0]] bankcontrol=dbconf.b_o[controls[:,1]] climbcontrol=dbconf.traf.avsdef*np.sign(controls[:,2]) # Now assign in the traf class -------------------------------------------- # Change autopilot desired speed dbconf.traf.asasspd=vtas2eas(np.where(acccontrol==0,dbconf.traf.gs,\ np.where(acccontrol>0,dbconf.vmax,dbconf.vmin)),dbconf.traf.alt) # Set acceleration for aircraft in conflict dbconf.traf.ax=np.where(dbconf.traf.asasactive,abs(acccontrol),kts) # Change autopilot desired heading dbconf.traf.asashdg=np.where(bankcontrol==0,dbconf.traf.trk,\ np.where(bankcontrol>0,dbconf.traf.trk+90,dbconf.traf.trk-90))%360 # Set bank angle for aircraft in conflict dbconf.traf.aphi=np.radians(np.where(dbconf.traf.asasactive,np.abs(bankcontrol),25.)) # Change autopilot desired altitude dbconf.traf.aalt=np.where(climbcontrol==0,dbconf.traf.alt,\ np.where(climbcontrol>0,1e9,-1e9)) # Set climb rate for aircraft in conflict dbconf.traf.asasvsp=np.abs(climbcontrol)