From 3d1f8121f64341ef07edbed12ad437348180fc97 Mon Sep 17 00:00:00 2001 From: Nino Date: Mon, 6 Dec 2021 16:23:15 +0100 Subject: [PATCH 01/13] Fix indexing in autopilot "potential current climb/descent stop" logic --- bluesky/traffic/autopilot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bluesky/traffic/autopilot.py b/bluesky/traffic/autopilot.py index 98a25a66a5..3df5576754 100644 --- a/bluesky/traffic/autopilot.py +++ b/bluesky/traffic/autopilot.py @@ -502,7 +502,7 @@ def ComputeVNAV(self, idx, toalt, xtoalt, torta, xtorta): # then stop immediately, as in: do not make it worse. if bs.traf.vs[idx]>0.0001: self.vnavvs[idx] = 0.0 - self.alt = bs.traf.alt[idx] + self.alt[idx] = bs.traf.alt[idx] if bs.traf.swvnav[idx]: bs.traf.selalt[idx] = bs.traf.alt[idx] @@ -557,7 +557,7 @@ def ComputeVNAV(self, idx, toalt, xtoalt, torta, xtorta): # then stop immediately, as in: do not make it worse. if bs.traf.vs[idx] < -0.0001: self.vnavvs[idx] = 0.0 - self.alt = bs.traf.alt[idx] + self.alt[idx] = bs.traf.alt[idx] if bs.traf.swvnav[idx]: bs.traf.selalt[idx] = bs.traf.alt[idx] From ee75867eb034e5644bead37df3db81c56e5205a5 Mon Sep 17 00:00:00 2001 From: Nino Date: Sun, 9 Jan 2022 17:14:15 +0100 Subject: [PATCH 02/13] Included information on how to manually build setup.py for cbased function in the tools and asas directories --- bluesky/tools/__init__.py | 2 +- bluesky/tools/src_cpp/README.txt.txt | 8 ++++++++ bluesky/traffic/asas/src_cpp/README.txt.txt | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 bluesky/tools/src_cpp/README.txt.txt create mode 100644 bluesky/traffic/asas/src_cpp/README.txt.txt diff --git a/bluesky/tools/__init__.py b/bluesky/tools/__init__.py index 91f97b75cb..3aa2a12fb1 100644 --- a/bluesky/tools/__init__.py +++ b/bluesky/tools/__init__.py @@ -1,6 +1,6 @@ from bluesky import settings # Register settings defaults -settings.set_variable_defaults(prefer_compiled=False) +settings.set_variable_defaults(prefer_compiled=True) if settings.prefer_compiled: try: from . import cgeo as geo diff --git a/bluesky/tools/src_cpp/README.txt.txt b/bluesky/tools/src_cpp/README.txt.txt new file mode 100644 index 0000000000..3ba50d46a9 --- /dev/null +++ b/bluesky/tools/src_cpp/README.txt.txt @@ -0,0 +1,8 @@ +Note, to make use of this you currently still have to manually compile +the extension by running: +python setup.py build_ext --inplace +in bluesky/tools/src_cpp +and copying/moving the resulting cgeo.[so/dll] to bluesky/tools. + +In bluesky/tools/__init__, change the variable prefer_compiled +to True if not read correctly from settings.cfg \ No newline at end of file diff --git a/bluesky/traffic/asas/src_cpp/README.txt.txt b/bluesky/traffic/asas/src_cpp/README.txt.txt new file mode 100644 index 0000000000..01a5384aa8 --- /dev/null +++ b/bluesky/traffic/asas/src_cpp/README.txt.txt @@ -0,0 +1,5 @@ +Note, to make use of this you currently still have to manually compile +the extension by running: +python setup.py build_ext --inplace +in bluesky/traffic/asas/src_cpp +and copying/moving the resulting casas.[so/dll] to bluesky/traffic/asas. \ No newline at end of file From 100d5c925a6bda5f690d61f3f781c9cdcf79897f Mon Sep 17 00:00:00 2001 From: Nino Date: Thu, 21 Apr 2022 15:29:07 +0200 Subject: [PATCH 03/13] Delete unneccesary print statement --- plugins/windgfs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/windgfs.py b/plugins/windgfs.py index a36cfe6bda..96a63e7704 100644 --- a/plugins/windgfs.py +++ b/plugins/windgfs.py @@ -159,7 +159,6 @@ def loadwind(self, lat0: 'lat', lon0: 'lon', lat1: 'lat', lon1: 'lon', pred = 3 elif self.hour == 24: ymd0 = "%04d%02d%02d" % (self.year, self.month, self.day) - print(ymd0) ymd1 = (datetime.datetime.strptime(ymd0, '%Y%m%d') + datetime.timedelta(days=1)) self.year = ymd1.year From 9e54515d0e65d0e42e1ae0f74ba601e050763d67 Mon Sep 17 00:00:00 2001 From: Nino Date: Thu, 21 Apr 2022 15:43:31 +0200 Subject: [PATCH 04/13] Remove bug from opensky plugin. Number of aircraft is not valid entry for the traffic cre function. --- plugins/opensky.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/opensky.py b/plugins/opensky.py index 04f321d945..d0666c8cba 100644 --- a/plugins/opensky.py +++ b/plugins/opensky.py @@ -150,7 +150,7 @@ def update(self): if n_new: actype = [actypes.get(str(i), 'B744') for i in icao24[newac]] for j in range(n_new): - traf.cre(n_new, acid[newac][j], actype[j], lat[newac][j], lon[newac][j],\ + traf.cre(acid[newac][j], actype[j], lat[newac][j], lon[newac][j],\ hdg[newac][j], alt[newac][j], spd[newac][j]) self.my_ac[-n_new:] = True From eff314822341eb3ae119c02d3fb3de5a1657cdc6 Mon Sep 17 00:00:00 2001 From: Nino Date: Thu, 21 Apr 2022 15:51:18 +0200 Subject: [PATCH 05/13] The intented Mach number rather than the traf.M should be used to calculate the limits. When aircraft fly at/near max Mach, the traf.M can be above max Mach due to simulation time step differences, resulting in a Mach limit based on mmo. Even when a reduction of speed is intended based on conflict resolution. This causes the aircraft to get "stuck" at mmo. --- bluesky/traffic/performance/bada/perfbada.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bluesky/traffic/performance/bada/perfbada.py b/bluesky/traffic/performance/bada/perfbada.py index a3d62199ac..80f0652ce9 100644 --- a/bluesky/traffic/performance/bada/perfbada.py +++ b/bluesky/traffic/performance/bada/perfbada.py @@ -1,7 +1,7 @@ """ BlueSky aircraft performance calculations using BADA 3.xx.""" import numpy as np import bluesky as bs -from bluesky.tools.aero import kts, ft, g0, vtas2cas, vcas2tas +from bluesky.tools.aero import kts, ft, g0, vtas2cas, vcas2tas, vtas2mach from bluesky.traffic.performance.perfbase import PerfBase from bluesky.traffic.performance.legacy.performance import esf, phases, calclimits, PHASE from bluesky import settings @@ -585,7 +585,7 @@ def limits(self, intent_v, intent_vs, intent_h, ax): self.limalt_flag, self.limvs, self.limvs_flag = calclimits( vtas2cas(intent_v, bs.traf.alt), bs.traf.gs, self.vmto, self.vmin, self.vmo, self.mmo, - bs.traf.M, bs.traf.alt, self.hmaxact, + vtas2mach(intent_v, bs.traf.alt), bs.traf.alt, self.hmaxact, intent_h, intent_vs, self.maxthr, self.thrust, self.D, bs.traf.tas, self.mass, self.ESF, self.phase) From 2761b3e80fcccf305a6bfdbe1e0b756e0a75fe02 Mon Sep 17 00:00:00 2001 From: Nino Date: Thu, 21 Apr 2022 15:55:20 +0200 Subject: [PATCH 06/13] Function to set aircraft mass for performance modelling --- bluesky/traffic/performance/perfbase.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bluesky/traffic/performance/perfbase.py b/bluesky/traffic/performance/perfbase.py index 62f0974b6d..8d997785f9 100644 --- a/bluesky/traffic/performance/perfbase.py +++ b/bluesky/traffic/performance/perfbase.py @@ -73,6 +73,14 @@ def engchange(self, acid: "acid", engine_id: "txt" = ""): "The currently selected performance model doesn't support engine changes.", ) + @command(name='MASS') + def selacmass(self, acid: 'acid', mass: 'float'): + """ MASS, acid, mass + + Select aircraft mass for performance model.""" + self.mass[acid] = mass + return True + @command(name="PERFSTATS", aliases=("PERFINFO", "PERFDATA")) def show_performance(self, acid: "acid"): """Show aircraft perfromance parameters for aircraft 'acid'""" From 58fb19fea37aac343c7266b9833bc7ed3e44c28e Mon Sep 17 00:00:00 2001 From: Nino Date: Thu, 21 Apr 2022 16:00:51 +0200 Subject: [PATCH 07/13] No conversion to CAS to be able to fly constant Mach to next waypoint, dependending on input scenario speed (CAS/Mach) --- bluesky/traffic/route.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/bluesky/traffic/route.py b/bluesky/traffic/route.py index f5ed25aadd..2459eff97f 100644 --- a/bluesky/traffic/route.py +++ b/bluesky/traffic/route.py @@ -895,14 +895,8 @@ def direct(acidx: 'acid', wpname: 'wpinroute'): else: alt = acrte.wpalt[wpidx] - # Check for valid Mach or CAS - if acrte.wpspd[wpidx] <2.0: - cas = mach2cas(acrte.wpspd[wpidx], alt) - else: - cas = acrte.wpspd[wpidx] - # Save it for next leg - bs.traf.actwp.nextspd[acidx] = cas + bs.traf.actwp.nextspd[acidx] = acrte.wpspd[wpidx] # No speed specified for next leg else: From 01739941070b847f877a7ef440faa7cd3962cdfb Mon Sep 17 00:00:00 2001 From: Nino Date: Thu, 21 Apr 2022 16:26:56 +0200 Subject: [PATCH 08/13] Implementing a vertical activation switch to avoid aircraft climbing in each others protected zone. Generally, this behavior is adequately captured by the mvp algorithm, except when one or more ac are at/near their maximum altitude and have no/little room to climb. --- bluesky/traffic/asas/mvp.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/bluesky/traffic/asas/mvp.py b/bluesky/traffic/asas/mvp.py index b113b42ef6..2530586d5c 100644 --- a/bluesky/traffic/asas/mvp.py +++ b/bluesky/traffic/asas/mvp.py @@ -1,6 +1,6 @@ ''' Conflict resolution based on the Modified Voltage Potential algorithm. ''' import numpy as np -from bluesky import stack +from bluesky import stack, settings from bluesky.traffic.asas import ConflictResolution @@ -166,19 +166,34 @@ def resolve(self, conf, ownship, intruder): # Initialize an array to store time needed to resolve vertically timesolveV = np.ones(ownship.ntraf) * 1e9 + + # Initialize an array to store if vs action is required irrespective of resolution domain + swvsact = np.zeros(ownship.ntraf, dtype=bool) # Call MVP function to resolve conflicts----------------------------------- for ((ac1, ac2), qdr, dist, tcpa, tLOS) in zip(conf.confpairs, conf.qdr, conf.dist, conf.tcpa, conf.tLOS): idx1 = ownship.id.index(ac1) idx2 = intruder.id.index(ac2) - + + # Determine largest RPZ and HPZ of the conflict pair + rpz_m = np.max(conf.rpz[[idx1, idx2]] * self.resofach) + hpz_m = np.max(conf.hpz[[idx1, idx2]] * self.resofacv) + # If A/C indexes are found, then apply MVP on this conflict pair # Because ADSB is ON, this is done for each aircraft separately if idx1 >-1 and idx2 > -1: - dv_mvp, tsolV = self.MVP(ownship, intruder, conf, qdr, dist, tcpa, tLOS, idx1, idx2) + dv_mvp, tsolV = self.MVP(ownship, intruder, conf, qdr, dist, tcpa, tLOS, idx1, idx2, rpz_m, hpz_m) if tsolV < timesolveV[idx1]: timesolveV[idx1] = tsolV + # Check if AC pair is in rpz and predicted to be in hpz next step + # hpz_m scaled with at least 1.2 resofacv for fast CL/DE traffic + hor_int = dist < rpz_m + ver_int = abs((ownship.alt[idx1] + ownship.vs[idx1]*settings.asas_dt) - \ + (intruder.alt[idx2] + intruder.vs[idx2]*settings.asas_dt)) < \ + hpz_m / self.resofacv * max(self.resofacv, 1.2) + swvsact[idx1] = np.logical_and(hor_int, ver_int) + # Use priority rules if activated if self.swprio: dv[idx1], _ = self.applyprio(dv_mvp, dv[idx1], dv[idx2], ownship.vs[idx1], intruder.vs[idx2]) @@ -261,15 +276,17 @@ def resolve(self, conf, ownship, intruder): # be equal to auto pilot alt (aalt). This is to prevent a new asasalt being computed # using the auto pilot vertical speed (ownship.avs) using the code in line 106 (asasalttemp) when only # horizontal resolutions are allowed. - alt = alt * (1 - self.swresohoriz) + ownship.selalt * self.swresohoriz - return newtrack, newgscapped, vscapped, alt + # Additionally remaining at current alt (ownship.alt) is forced when AC are + # in each others rpz and predicted to enter hpz based on vs and dt ASAS + alt = (alt * (1 - self.swresohoriz) + ownship.selalt * self.swresohoriz) * (1 - swvsact) \ + + ownship.alt * swvsact + + return newtrack, tascapped, vscapped, alt - def MVP(self, ownship, intruder, conf, qdr, dist, tcpa, tLOS, idx1, idx2): + def MVP(self, ownship, intruder, conf, qdr, dist, tcpa, tLOS, idx1, idx2, rpz_m, hpz_m): """Modified Voltage Potential (MVP) resolution method""" # Preliminary calculations------------------------------------------------- - # Determine largest RPZ and HPZ of the conflict pair, use lookahead of ownship - rpz_m = np.max(conf.rpz[[idx1, idx2]] * self.resofach) - hpz_m = np.max(conf.hpz[[idx1, idx2]] * self.resofacv) + # Use lookahead of ownship dtlook = conf.dtlookahead[idx1] # Convert qdr from degrees to radians qdr = np.radians(qdr) From ebe41456e1743b5667da0e6234644d30e0c8e67a Mon Sep 17 00:00:00 2001 From: Nino Date: Thu, 21 Apr 2022 16:30:57 +0200 Subject: [PATCH 09/13] Capping the performance limits based on the general (BADA/OpenAP) bs.traf.perf.limits function instead of the OpenAP specific limits. Therefore, speed is converted from GS to TAS and the right vertical speed direction is set. --- bluesky/traffic/asas/mvp.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/bluesky/traffic/asas/mvp.py b/bluesky/traffic/asas/mvp.py index 2530586d5c..d67d04a2ae 100644 --- a/bluesky/traffic/asas/mvp.py +++ b/bluesky/traffic/asas/mvp.py @@ -1,5 +1,6 @@ ''' Conflict resolution based on the Modified Voltage Potential algorithm. ''' import numpy as np +import bluesky as bs from bluesky import stack, settings from bluesky.traffic.asas import ConflictResolution @@ -250,11 +251,16 @@ def resolve(self, conf, ownship, intruder): # Determine ASAS module commands for all aircraft-------------------------- - # Cap the velocity - newgscapped = np.maximum(ownship.perf.vmin,np.minimum(ownship.perf.vmax,newgs)) - - # Cap the vertical speed - vscapped = np.maximum(ownship.perf.vsmin,np.minimum(ownship.perf.vsmax,newvs)) + # Compute the true airspeed from newgs (GS=TAS if no wind) + vwn, vwe = bs.traf.wind.getdata(bs.traf.lat, bs.traf.lon, bs.traf.alt) + newtasnorth = newgs * np.cos(np.radians(newtrack)) - vwn + newtaseast = newgs * np.sin(np.radians(newtrack)) - vwe + newtas = np.sqrt(newtasnorth**2 + newtaseast**2) + + # Cap the velocity and vertical speed + tascapped, vscapped, altcapped = bs.traf.perf.limits(newtas, newvs, ownship.alt, ownship.ax) + signvs = np.sign(newvs) + vscapped = np.where(np.logical_or(signvs == 0, signvs == np.sign(vscapped)), vscapped, -vscapped) # Calculate if Autopilot selected altitude should be followed. This avoids ASAS from # climbing or descending longer than it needs to if the autopilot leveloff From 716e95ce666bd73efa23c80f943c515cf9963a5b Mon Sep 17 00:00:00 2001 From: Nino Date: Thu, 21 Apr 2022 16:34:58 +0200 Subject: [PATCH 10/13] The mvp function returns the TAS, therefore the convertion step is discarded in aporasas. Another option is to convert the TAS in the MVP back to GS, however, this causes conversion errors that result in loss of separations for aircraft flying (near) max Mach/altitude. --- bluesky/traffic/aporasas.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/bluesky/traffic/aporasas.py b/bluesky/traffic/aporasas.py index cc01fe945f..8f0d2be0bb 100644 --- a/bluesky/traffic/aporasas.py +++ b/bluesky/traffic/aporasas.py @@ -23,21 +23,11 @@ def create(self, n=1): def update(self): #--------- Input to Autopilot settings to follow: destination or ASAS ---------- - # Convert the ASAS commanded speed from ground speed to TAS - if bs.traf.wind.winddim > 0: - vwn, vwe = bs.traf.wind.getdata(bs.traf.lat, bs.traf.lon, bs.traf.alt) - asastasnorth = bs.traf.cr.tas * np.cos(np.radians(bs.traf.cr.trk)) - vwn - asastaseast = bs.traf.cr.tas * np.sin(np.radians(bs.traf.cr.trk)) - vwe - asastas = np.sqrt(asastasnorth**2 + asastaseast**2) - # no wind, then ground speed = TAS - else: - asastas = bs.traf.cr.tas # TAS [m/s] - # Select asas if there is a conflict AND resolution is on # Determine desired states per channel whether to use value from ASAS or AP. # bs.traf.cr.active may be used as well, will set all of these channels self.trk = np.where(bs.traf.cr.hdgactive, bs.traf.cr.trk, bs.traf.ap.trk) - self.tas = np.where(bs.traf.cr.tasactive, asastas, bs.traf.ap.tas) + self.tas = np.where(bs.traf.cr.tasactive, bs.traf.cr.tas, bs.traf.ap.tas) self.alt = np.where(bs.traf.cr.altactive, bs.traf.cr.alt, bs.traf.ap.alt) self.vs = np.where(bs.traf.cr.vsactive, bs.traf.cr.vs, bs.traf.ap.vs) From 81fb027b7e1c50bebdeb67b00e8730de07815a71 Mon Sep 17 00:00:00 2001 From: Nino Date: Fri, 29 Apr 2022 13:33:14 +0200 Subject: [PATCH 11/13] Merge branch 'master' of https://github.com/ninyes/bluesky --- bluesky/stack/basecmds.py | 2 +- bluesky/ui/pygame/fastfont.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bluesky/stack/basecmds.py b/bluesky/stack/basecmds.py index 13908a0fb1..cbc5c1e39b 100644 --- a/bluesky/stack/basecmds.py +++ b/bluesky/stack/basecmds.py @@ -178,7 +178,7 @@ def initbasecmds(): bs.navdb.defwpt, "Define a waypoint only for this scenario/run", ], - "DEL": [ + "DEL": [ "DEL acid/ALL/WIND/shape", "acid/txt,...", lambda *a: bs.traf.wind.clear() diff --git a/bluesky/ui/pygame/fastfont.py b/bluesky/ui/pygame/fastfont.py index fea5810da7..178097fc93 100644 --- a/bluesky/ui/pygame/fastfont.py +++ b/bluesky/ui/pygame/fastfont.py @@ -58,9 +58,9 @@ def printat(self,screen,x,y,text): ix = ix+self.chw[ich-32] # chimg = self.chmaps[ich-32].convert_alpha(screen) - txtimg.blit(self.chmaps[ich-32],dest,None,pg.BLEND_ADD) + txtimg.blit(self.chmaps[ich-32],dest)# Removed pg.BLEND_ADD which broke it on Windows machine - dest = txtimg.get_rect() + dest = txtimg.get_rect() # Set position if self.swposx <0: @@ -78,7 +78,7 @@ def printat(self,screen,x,y,text): dest.centery = y # Paste it onto the screen - screen.blit(txtimg,dest,None,pg.BLEND_ADD) + screen.blit(txtimg,dest)# Removed pg.BLEND_ADD which broke it on Windows machine return From d1ec70ecccabcda72c5d3615962f0bbcf83ac56b Mon Sep 17 00:00:00 2001 From: Nino Date: Tue, 3 May 2022 10:00:40 +0200 Subject: [PATCH 12/13] Revert "The mvp function returns the TAS, therefore the convertion step is discarded in aporasas. Another option is to convert the TAS in the MVP back to GS, however, this causes conversion errors that result in loss of separations for aircraft flying (near) max Mach/altitude." This reverts commit 716e95ce666bd73efa23c80f943c515cf9963a5b. --- bluesky/traffic/aporasas.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bluesky/traffic/aporasas.py b/bluesky/traffic/aporasas.py index 8f0d2be0bb..cc01fe945f 100644 --- a/bluesky/traffic/aporasas.py +++ b/bluesky/traffic/aporasas.py @@ -23,11 +23,21 @@ def create(self, n=1): def update(self): #--------- Input to Autopilot settings to follow: destination or ASAS ---------- + # Convert the ASAS commanded speed from ground speed to TAS + if bs.traf.wind.winddim > 0: + vwn, vwe = bs.traf.wind.getdata(bs.traf.lat, bs.traf.lon, bs.traf.alt) + asastasnorth = bs.traf.cr.tas * np.cos(np.radians(bs.traf.cr.trk)) - vwn + asastaseast = bs.traf.cr.tas * np.sin(np.radians(bs.traf.cr.trk)) - vwe + asastas = np.sqrt(asastasnorth**2 + asastaseast**2) + # no wind, then ground speed = TAS + else: + asastas = bs.traf.cr.tas # TAS [m/s] + # Select asas if there is a conflict AND resolution is on # Determine desired states per channel whether to use value from ASAS or AP. # bs.traf.cr.active may be used as well, will set all of these channels self.trk = np.where(bs.traf.cr.hdgactive, bs.traf.cr.trk, bs.traf.ap.trk) - self.tas = np.where(bs.traf.cr.tasactive, bs.traf.cr.tas, bs.traf.ap.tas) + self.tas = np.where(bs.traf.cr.tasactive, asastas, bs.traf.ap.tas) self.alt = np.where(bs.traf.cr.altactive, bs.traf.cr.alt, bs.traf.ap.alt) self.vs = np.where(bs.traf.cr.vsactive, bs.traf.cr.vs, bs.traf.ap.vs) From dde2e955f4ffaaa5f46b3e041aab9adfdf277fb3 Mon Sep 17 00:00:00 2001 From: Nino Date: Tue, 3 May 2022 10:00:50 +0200 Subject: [PATCH 13/13] Revert "Capping the performance limits based on the general (BADA/OpenAP) bs.traf.perf.limits function instead of the OpenAP specific limits. Therefore, speed is converted from GS to TAS and the right vertical speed direction is set." This reverts commit ebe41456e1743b5667da0e6234644d30e0c8e67a. --- bluesky/traffic/asas/mvp.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/bluesky/traffic/asas/mvp.py b/bluesky/traffic/asas/mvp.py index d67d04a2ae..2530586d5c 100644 --- a/bluesky/traffic/asas/mvp.py +++ b/bluesky/traffic/asas/mvp.py @@ -1,6 +1,5 @@ ''' Conflict resolution based on the Modified Voltage Potential algorithm. ''' import numpy as np -import bluesky as bs from bluesky import stack, settings from bluesky.traffic.asas import ConflictResolution @@ -251,16 +250,11 @@ def resolve(self, conf, ownship, intruder): # Determine ASAS module commands for all aircraft-------------------------- - # Compute the true airspeed from newgs (GS=TAS if no wind) - vwn, vwe = bs.traf.wind.getdata(bs.traf.lat, bs.traf.lon, bs.traf.alt) - newtasnorth = newgs * np.cos(np.radians(newtrack)) - vwn - newtaseast = newgs * np.sin(np.radians(newtrack)) - vwe - newtas = np.sqrt(newtasnorth**2 + newtaseast**2) - - # Cap the velocity and vertical speed - tascapped, vscapped, altcapped = bs.traf.perf.limits(newtas, newvs, ownship.alt, ownship.ax) - signvs = np.sign(newvs) - vscapped = np.where(np.logical_or(signvs == 0, signvs == np.sign(vscapped)), vscapped, -vscapped) + # Cap the velocity + newgscapped = np.maximum(ownship.perf.vmin,np.minimum(ownship.perf.vmax,newgs)) + + # Cap the vertical speed + vscapped = np.maximum(ownship.perf.vsmin,np.minimum(ownship.perf.vsmax,newvs)) # Calculate if Autopilot selected altitude should be followed. This avoids ASAS from # climbing or descending longer than it needs to if the autopilot leveloff